javascript - 将innerhtml拆分为文本以在javascript中翻译JSON
问题描述
目前,我正在开发一个应用程序,该应用程序需要提取 Body 的 innerHTML,然后以 JSON 格式从中取出文本。该 JSON 将用于翻译,然后翻译后的 JSON 将用作输入以创建相同的 HTML 标记,但带有翻译后的文本。请看下面的片段。
HTML 输入
<section>Hello, <div>This is some text which I need to extract.<a class="link">It can be <strong> complicated.</strong></a></div><span>The extracted text should contain the html tag if it has any html tag in the span,p or a tag</span><p>Please see the <span>desired output below.</span></p>Thanks!</section>';
翻译 JSON 输出
{
"text1":"Hello, ",
"text2":"This is some text which I need to extract.",
"text3":"It can be <strong> complicated.</strong>",
"text4":"The extracted text should contain the html tag if it
has any html tag in the span,p or a tag",
"text5":"Please see the <span>desired output below.</span>",
"text6":"Thanks!"
}
翻译后的 JSON 输入
{
"text1":"Hello,-in spanish ",
"text2":"This is some text which I need to extract.-in spanish",
"text3":"It can be <strong> complicated.-in spanish</strong>",
"text4":"The extracted text should contain the html tag if it
has any html tag in the span,p or a tag-in spanish",
"text5":"Please see the <span>desired output below.-in spanish</span>",
"text6":"Thanks!-in spanish"
}
翻译后的 HTML 输出
<section>Hello,-in spanish <div>This is some text which I need to extract.-in spanish<a class="link">It can be <strong> complicated.-in spanish</strong></a></div><span>The extracted text should contain the html tag if it has any html tag in the span,p or a tag-in spanish</span><p>Please see the <span>desired output below.</span></p>Thanks!-in spanish</section>';
我尝试了各种正则表达式,但下面是我最终完成的流程之一,但我无法通过它实现所需的输出。
//encode
const bodyHTML = '<a class="test">hello world<strong> this is gonna be hard</strong></a>';
//replace the quotes with escape quotes
const htmlContent = bodyHTML.replace(/"/g, '\\"');
let count = 0;
let translationObj = {};
let newHtml = htmlContent.replace(/\>(.*?)\</g, function(match) {
//remove the special character
match = match.replace(/\>|\</g, '');
count = count + 1;
translationObj[count] = match;
return '>~' + count + '~<';
});
const translationJSON = '{"1":"hello world in spanish","2":" this is gonna be hard in spanish","3":""}';
//decode
let trasnaltedHtml = '';
const translatedObj = JSON.parse(translationJSON)
trasnaltedHtml = newHtml.replace(/\~(.*?)\~/g, function(match) {
//remove the special character
match = match.replace(/\~|\~/g, '');
return translatedObj[match];
});
//replace the escape quotes with quotes
trasnaltedHtml = trasnaltedHtml.replace(/\\"/g, '"');
//console.log()
console.log("bodyHTML", bodyHTML);
console.log('tranlationObj', translationObj);
console.log("translationJSON", translationJSON);
console.log('newHtml', newHtml);
console.log("trasnaltedHtml", trasnaltedHtml);
我正在寻找一个有效的正则表达式或 JS 世界中的任何其他方法来获得预期的结果。我想以 JSON 的形式获取 HTML 中的所有文本。另一个条件是如果文本有一些内部 html 标记,则不要拆分文本,这样我们就不会失去句子的上下文,因为
<p>Click <a>here</a></p>
它应该被视为一个文本"Click <a>here</a>"
。我希望我澄清了所有的疑问
提前致谢 !
解决方案
到目前为止,最好的方法是使用 HTML 解析器,然后遍历树中的文本节点。您无法仅使用简单的 JavaScript 正则表达式来正确处理像 HTML 这样的非常规标记语言¹(许多人已经浪费了很多时间尝试),而且这甚至没有考虑到 HTML 的所有特定特性。
在npm
.
所以基本结构是:
将 HTML 解析为 DOM。
以定义的顺序(通常是深度优先遍历)遍历 DOM,构建您的对象或文本字符串数组以从您遇到的文本节点进行翻译。
如有必要,将该对象/数组转换为 JSON,将其发送出去进行翻译,取回结果,如有必要,再次将其从 JSON 解析为对象/数组。
以相同的顺序遍历 DOM,应用来自对象/数组的结果。
将 DOM 序列化为 HTML。
发送结果。
这是一个示例——当然,这里我使用的是内置于浏览器中的 HTML 解析器,而不是一个npm
模块,您使用的任何模块的 API 可能略有不同,但概念是相同的:
var html = '<section>Hello, <div>This is some text which I need to extract.<a class="link">It can be <strong> complicated.</strong></a></div><span>The extracted text should contain the html tag if it has any html tag in the span,p or a tag</span><p>Please see the <span>desired output below.</span></p>Thanks!</section>';
var dom = parseHTML(html);
var strings = [];
walk(dom, function(node) {
if (node.nodeType === 3) { // text node
strings.push(node.nodeValue);
}
});
console.log("strings = ", strings);
var translation = translate(strings);
console.log("translation = ", translation);
var n = 0;
walk(dom, function(node) {
if (node.nodeType === 3) { // text node
node.nodeValue = translation[n++];
}
});
var newHTML = serialize(dom);
document.getElementById("before").innerHTML = html;
document.getElementById("after").innerHTML = newHTML;
function translate(strings) {
return strings.map(str => str.toUpperCase());
}
function walk(node, callback) {
var child;
callback(node);
switch (node.nodeType) {
case 1: // Element
for (child = node.firstChild; child; child = child.nextSibling) {
walk(child, callback);
}
}
}
// Placeholder for module function
function parseHTML(html) {
var div = document.createElement("div");
div.innerHTML = html;
return div;
}
// Placeholder for module function
function serialize(dom) {
return dom.innerHTML;
}
<strong>Before:</strong>
<div id="before"></div>
<strong>After:</strong>
<div id="after"></div>
¹一些“正则表达式”库(或其他语言的正则表达式功能)确实是正则表达式+更多功能,可以帮助您做类似的事情,但它们不仅仅是正则表达式,JavaScript 的内置库没有这些功能。
推荐阅读
- r - R survminer 95%CI 估计方法
- java - 通过 t3 协议访问 weblogic 服务器上的 jndi 数据源与直接访问数据库有何不同?
- methods - ActiveRecord 通过 has_many 删除行:通过关联
- python - 将文档存储到 Elastic Search 中现有和不存在的字段中
- ios - 当我的应用程序根据条件关闭时,是否可以禁止推送通知?
- sql - 将 SQL Server 中已弃用的外连接运算符 *= 转换为左连接
- nestjs - 如何在 NestJS 中序列化 Prisma 对象?
- php - 如果没有可用的运输选项,则阻止查看结帐页面 WooCommerce
- expo - 事件监听器不会在 expo、react-navigation 中触发,但用于之前工作
- spring-boot - 将 Apache Spark 与 Spring Boot 集成