将innerhtml拆分为文本以在javascript中翻译JSON

Posted

技术标签:

【中文标题】将innerhtml拆分为文本以在javascript中翻译JSON【英文标题】:Split innerhtml into text for translation JSON in javascript 【发布时间】:2018-11-02 17:25:24 【问题描述】:

目前我正在开发一个应用程序,该应用程序需要提取 Body 的 innerhtml,然后以 JSON 格式从中取出文本。该 JSON 将用于翻译,然后翻译后的 JSON 将用作输入以创建相同的 HTML 标记,但带有翻译后的文本。请看下面的sn-p。

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 标签,则不要拆分文本,这样我们就不会丢失句子的上下文,例如 &lt;p&gt;Click &lt;a&gt;here&lt;/a&gt;&lt;/p&gt; 它应该被视为一个文本"Click &lt;a&gt;here&lt;/a&gt;"。我希望我澄清了所有的疑问

提前致谢!

【问题讨论】:

您可以在客户端中提取文本,例如:jQuery( "body:contains(Text)" ).text() - 如果您的可提取元素具有特定的 css 类,您可以进行增强 哦哦。有人正在用正则表达式解析 HTML。不过,说真的,也许寻找类似 JSoup for JS 的东西。除非我误解了这一点。 如何判断一个 HTML 标签是否是一个内部标签?在您的示例中,您说您希望 &lt;div&gt;This is some[...] to extract.&lt;a class="link"&gt;It can be &lt;strong&gt; complicated.&lt;/strong&gt;&lt;/a&gt;&lt;/div&gt; 成为 This is some text which I need to extract."/"It can be &lt;strong&gt; complicated.&lt;/strong&gt;"。但是在你说你想让&lt;p&gt;Click &lt;a&gt;here&lt;/a&gt;&lt;/p&gt;变成"Click here"之后。 我将使用 Node.js 创建类似用于翻译的微服务@T.J.Crowder 非常感谢@T.J.Crowder 指导我完成这个过程。今天肯定学到了一些新东西,但这和我的 sn-p 做的一样。我的目标是让It can be &lt;strong&gt; complicated.&lt;/strong&gt; 在一起。 【参考方案1】:

到目前为止,最好的方法是使用 HTML 解析器,然后循环遍历树中的文本节点。您无法仅使用简单的 javascript 正则表达式来正确处理像 HTML 这样的非常规标记语言¹(许多人已经浪费了很多时间来尝试),而且这甚至没有考虑到 HTML 的所有特定特性。

npm 上至少有几个,可能是几个,经过充分测试,积极支持的 DOM 解析器模块。

所以基本结构是:

    将 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 的内置功能不没有这些功能。

【讨论】:

【参考方案2】:

如果有人想做这样的事情,那么我在这里创建了这个翻译服务

https://github.com/gurusewak/translation

我的目标不是要达到 100% 的破句成功率,而是要尽可能多地获得句子。当给定一些 html 作为输入时,我只是想帮助某人进行翻译。希望这可能会在将来以某种方式帮助某人。

干杯!

输出

Output of the flow here

【讨论】:

以上是关于将innerhtml拆分为文本以在javascript中翻译JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何将 javascript var 的 innerHTML 设置为 php/html 文本

将 Html 转换为像字符串一样显示

将 innerhtml 添加到顶部链接

将字符串拆分为文本和数字

将文本拆分为句子

使用 innerHTML 更改页面上的所有文本