前言:
当前你们对“正则表达式标点符号匹配”大致比较关怀,兄弟们都需要剖析一些“正则表达式标点符号匹配”的相关资讯。那么小编同时在网络上网罗了一些对于“正则表达式标点符号匹配””的相关内容,希望兄弟们能喜欢,姐妹们快快来了解一下吧!场景
为了锻炼英文阅读能力, 在英文文章阅读时还是期望能多读外文, 如果一把梭翻译一遍, 普遍是只读中文不看英文了, 那么也就起不到我们锻炼英文能力的要求了.
需求
如果我遇到了一些不认识或者不确定意思的单词,我希望得到一个贴合当前语境的翻译,这样既能理解文章,又能在语境中学习单词。
需求拆解
如果鼠标在某个单词上方悬浮超过 xx 毫秒, 那么则结合当前语境翻译这个单词及这个句子.
好的, 需求有了, 思路也有了, 具体咋做咱就不知道了, 现在轮到我最强的小弟 ChatGPT 大显身手了
效果图
具体功能点:
关键词的翻译, 译文紧跟在关键词后面当前语句的翻译
实现此效果的完整 ChatGPT 对话: 实现沉浸式翻译的核心功能
最终完整代码
import type { PlasmoCSConfig } from "plasmo"import { generate } from 'short-uuid'export const config: PlasmoCSConfig = { matches: ["<all_urls>"], all_frames: true}const loading = `<svg xmlns="; viewBox="0 0 200 200"><radialGradient id="a11" cx=".66" fx=".66" cy=".3125" fy=".3125" gradientTransform="scale(1.5)"><stop offset="0" stop-color="#85A2B6"></stop><stop offset=".3" stop-color="#85A2B6" stop-opacity=".9"></stop><stop offset=".6" stop-color="#85A2B6" stop-opacity=".6"></stop><stop offset=".8" stop-color="#85A2B6" stop-opacity=".3"></stop><stop offset="1" stop-color="#85A2B6" stop-opacity="0"></stop></radialGradient><circle transform-origin="center" fill="none" stroke="url(#a11)" stroke-width="15" stroke-linecap="round" stroke-dasharray="200 1000" stroke-dashoffset="0" cx="100" cy="100" r="70"><animateTransform type="rotate" attributeName="transform" calcMode="spline" dur="2" values="360;0" keyTimes="0;1" keySplines="0 0 1 1" repeatCount="indefinite"></animateTransform></circle><circle transform-origin="center" fill="none" opacity=".2" stroke="#85A2B6" stroke-width="15" stroke-linecap="round" cx="100" cy="100" r="70"></circle></svg>`const cssCode = `.ct-loading { width: 1em; display: inline-block;}.ct-span { display: inline-block; margin-right: 2px; margin-left: 2px;}`var xy = { x: 0, y: 0 }document.head.insertAdjacentHTML('beforeend', '<style type="text/css">' + cssCode + '</style>');// 存储已经翻译过的单词,以避免重复翻译var translatedWords = new Set(); // 用于存储已翻译的单词及其父元素var pool = {}document.addEventListener('mousemove', function (event) { // 获取鼠标位置 var x = event.clientX, y = event.clientY; xy = { x, y } // 获取鼠标位置下的文本范围 var range, textNode, offset; range = document.caretRangeFromPoint(x, y); textNode = range.startContainer; if (!textNode) { return } if (textNode.parentElement.hasAttribute('data-ct-translation')) { // 翻译结果节点 return; } if (hasPreOrCodeParent(textNode)) { return } offset = range.startOffset; var text = textNode.textContent; var words = text.split(/\s+/); for (var i = 0; i < words.length; i++) { var word = removeSpecialCharacters(words[i]); if (!isEnglishWord(word)) { continue; } // 检测鼠标是否在当前单词上 var wordRange = document.createRange(); wordRange.setStart(textNode, text.indexOf(word)); wordRange.setEnd(textNode, text.indexOf(word) + word.length); var rects = wordRange.getClientRects(); for (var j = 0; j < rects.length; j++) { var rect = rects[j]; if (!(x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom)) { continue; } var parentElementId = textNode.parentElement.getAttribute('data-ct-id'); if (parentElementId) { translatedWords[word] = parentElementId; } else { parentElementId = generate(); textNode.parentElement.setAttribute('data-ct-id', parentElementId); } if (translatedWords.has(word + '-' + parentElementId)) { continue; } // 创建包装的 span 元素 // console.log(); var spanElement = document.createElement('span'); const wordId = generate() spanElement.setAttribute('id', wordId); spanElement.setAttribute('data-pid', parentElementId); spanElement.setAttribute('data-ct-translation', '0'); spanElement.setAttribute('data-ct-word', word); spanElement.setAttribute('data-ct-rect', `${rect.left},${rect.right},${rect.top},${rect.bottom}`); spanElement.setAttribute('data-ct-parent', getFullSentenceContainingWord(textNode.parentElement)); wordRange.collapse(false); // 将光标移到范围的末尾 wordRange.insertNode(spanElement); translatedWords.add(word + '-' + parentElementId); pool[wordId] = {} // console.log('Word under mouse:', word); } }});setInterval(() => { for (const wordId in pool) { const wordElement = document.getElementById(wordId); if (!wordElement) { continue; } const rect = wordElement.getAttribute('data-ct-rect').split(',').map(Number); const word = wordElement.getAttribute('data-ct-word'); const pid = wordElement.getAttribute('data-pid'); if (!isMouseOnTranslation({ left: rect[0], right: rect[1], top: rect[2], bottom: rect[3] }, xy.x, xy.y)) { translatedWords.delete(word + '-' + pid) wordElement.remove() delete pool[wordId] continue } wordElement.classList.add('ct-loading') wordElement.innerHTML = loading fetch(';, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ word: word, sentence: wordElement.getAttribute('data-ct-parent') }) }).then(res => res.json()).then(res => { console.log(res) wordElement.classList.remove('ct-loading') wordElement.classList.add('ct-span') wordElement.innerHTML = `(${res.word_result})` const p = document.querySelector(`[data-ct-id="${pid}"]`) const cp = p.cloneNode(true) cp.textContent = res.sentence_result p.after(cp) }).catch(e => console.log) wordElement.setAttribute('data-ct-translation', '1'); delete pool[wordId] }}, 1500)// 判断鼠标是否在翻译内容上function isMouseOnTranslation(rect, mouseX, mouseY) { return rect && mouseX >= rect.left && mouseX <= rect.right && mouseY >= rect.top && mouseY <= rect.bottom}function isEnglishWord(word) { // 使用正则表达式匹配英文单词,这里假设一个英文单词由大小写字母组成 var regex = /^[a-zA-Z0-9]+$/; return regex.test(removePunctuation(word));}function removePunctuation(word) { // 使用正则表达式匹配标点符号并替换为空字符串 return word.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, '');}function getFullSentenceContainingWord(parentNode) { // const tokens = parentNode.innerText.replace(/\n/, '').split('.'); // return tokens[0]; return parentNode.innerText.replace(/\n/, '')}function removeSpecialCharacters(str) { return str.replace(/[^a-zA-Z0-9]/g, '');}function hasPreOrCodeParent(node) { let parent = node.parentNode; while (parent) { if (parent.tagName === 'PRE' || parent.tagName === 'CODE') { return true; } parent = parent.parentNode; } return false;}
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #正则表达式标点符号匹配 #正则表达式标点符号匹配怎么用