Find and replace specific text characters across a document with JS
我想知道是否有一种轻量级的方法可以使用javascript或jquery在文档中嗅出一个特定的文本字符,比如说欧元,并找到这个字符的所有实例。然后!写一个功能,用一个美元来替换这个的所有实例。
我为初学者找到了这个片段:
1 2 3 | var str = 'test: ''; str = str.replace(/'/g,"'"); |
本质上,我想要一个单页文档的解决方案。获取x的所有实例并使其成为xy。仅文本字符。
用
1 2 3 | $("body").children().each(function () { $(this).html( $(this).html().replace(/@/g,"$") ); }); |
http://jsfiddle.net/maximua/jp96c/1/
我自己的建议如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function nativeSelector() { var elements = document.querySelectorAll("body, body *"); var results = []; var child; for(var i = 0; i < elements.length; i++) { child = elements[i].childNodes[0]; if(elements[i].hasChildNodes() && child.nodeType == 3) { results.push(child); } } return results; } var textnodes = nativeSelector(), _nv; for (var i = 0, len = textnodes.length; i<len; i++){ _nv = textnodes[i].nodeValue; textnodes[i].nodeValue = _nv.replace(/£/g,'€'); } |
。
JS小提琴演示。
ECMASCRIPT 2015+Approach当完成这项任务时
这似乎是一个简单的任务,但你必须照顾好一些事情:
- 简单地替换整个HTML杀死所有DOM功能,就像事件列表
- 替换HTML也可以替换
或 Contents,or HTML Tags or Attributes,which is not always desired
- 改变HTML可能在一次XSS攻击中产生
- 你可能想重新设置属性如EDOCX1&2&EDOCX1&3
对XSS一般攻击的警戒不能通过下面的办法解决。如果在页面上某个地方呼叫URL,那么下面的功能就不会停止,因为这一场景是不安全的。
Replacing the text contents of all elements
这基本上选择了所有包含正常文本的元素,通过他们的孩子节点吗?This basically selects all elements that contain normal text,goes through their child nodes?-什么?这些也有文本节点吗?-Seeks those text nodes out and replaces their contents.
你可以选择一个不同的根
1 2 3 4 5 6 7 8 9 10 11 | const replaceOnDocument = (pattern, string, {target = document.body} = {}) => { // Handle `string`?—?see the last section [ target, ...target.querySelectorAll("*:not(script):not(noscript):not(style)") ].forEach(({childNodes: [...nodes]}) => nodes .filter(({nodeType}) => nodeType === document.TEXT_NODE) .forEach((textNode) => textNode.textContent = textNode.textContent.replace(pattern, string))); }; replaceOnDocument(/€/g,"$"); |
替换文本节点、元素属性和属性
现在,这是一个较小的复杂性:你需要检查三个案例:当一个节点是一个文本节点时,当它是一个元素及其属性应当替换时,或者当它是一个元素及其属性应当替换时。对象为文本节点和元素提供了方法。
在重新配置属性和属性之前,需要重新配置属性,以检查元素具有匹配属性的地方;否则,需要新的属性来创建。它还需要检查目标属性是一条弦的位置,因为只有弦可以被替换,或者匹配属性不是一个功能,因为这可能引导一个XSS攻击。
在下面的例子中,你可以看到如何利用扩展的特征:在第三个选择性论据中,你可以添加一个EDOCX1[…]9],Property and a EDOCX1[…]10,]Property,which is an Iterable(E.G.An Array)each,for the attributes to be replaced and the properties to be replaced,respectively.
你也会注意到这辆Snippet正在使用
ZZU1重置HTML entities
如果你需要使用诸如
因此,让我们通过输入字符串解决这个问题,接受一个HTML字符串:一个新的,暂时的
1 | string = new DOMParser().parseFromString(string,"text/html").documentElement.textContent; |
如果你想使用这个,选择一个以上的方法,取决于你是否想将HTML属性和DOM属性添加到文本中;然后简单地将EDOCX1[…]替换为文本。
现在你可以使用EDOCX1
如果你不使用弦乐处理代码,你也可以将
注意到这一部分HTML实体,但由于我们只阅读了EDOCX1[…]24,]因此仍然无法插入实际的HTML标签。这也是针对XSS的最安全案例:自从我们使用
你还应该考虑使用
在不使用jquery的javascript中:
1 | document.body.innerText = document.body.innerText.replace('actualword', 'replacementword'); |
Similar to@max-malik's answer,but without using Jquery,you can also do this using document.creattreeewalker:
1 2 3 4 5 6 7 | button.addEventListener('click', e => { const treeWalker = document.createTreeWalker(document.body); while (treeWalker.nextNode()) { const node = treeWalker.currentNode; node.textContent = node.textContent.replace(/@/g, '$'); } }) |
1 2 3 4 5 6 7 | This is an @ that we are @ replacing. This is another @ that we are replacing. <span>This is an @ in a span in @ div.</span> <input id="button" type="button" value="Replace @ with $" /> |
使用拆分和联接方法
1 2 3 4 5 | $("#idBut").click(function() { $("body").children().each(function() { $(this).html($(this).html().split('@').join("$")); }); }); |
这是解决方案
最好是在服务器端执行此操作,或者在将货币符号返回浏览器之前将其包装在可以选择的元素中,但是如果两者都不是选项,则可以选择正文中的所有文本节点并对其执行替换。下面我用了两年前我写的一个插件来做这个,这个插件是用来突出显示文本的。我要做的是找到所有出现的欧元,并用类货币符号将其包装在一个范围内,然后替换这些范围的文本。
演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | (function($){ $.fn.highlightText = function () { // handler first parameter // is the first parameter a regexp? var re, hClass, reStr, argType = $.type(arguments[0]), defaultTagName = $.fn.highlightText.defaultTagName; if ( argType ==="regexp" ) { // first argument is a regular expression re = arguments[0]; } // is the first parameter an array? else if ( argType ==="array" ) { // first argument is an array, generate // regular expression string for later use reStr = arguments[0].join("|"); } // is the first parameter a string? else if ( argType ==="string" ) { // store string in regular expression string // for later use reStr = arguments[0]; } // else, return out and do nothing because this // argument is required. else { return; } // the second parameter is optional, however, // it must be a string or boolean value. If it is // a string, it will be used as the highlight class. // If it is a boolean value and equal to true, it // will be used as the third parameter and the highlight // class will default to"highlight". If it is undefined, // the highlight class will default to"highlight" and // the third parameter will default to false, allowing // the plugin to match partial matches. // ** The exception is if the first parameter is a regular // expression, the third parameter will be ignored. argType = $.type(arguments[1]); if ( argType ==="string" ) { hClass = arguments[1]; } else if ( argType ==="boolean" ) { hClass ="highlight"; if ( reStr ) { reStr ="\\b" + reStr +"\\b"; } } else { hClass ="highlight"; } if ( arguments[2] && reStr ) { reStr = reStr ="\\b" + reStr +"\\b"; } // if re is not defined ( which means either an array or // string was passed as the first parameter ) create the // regular expression. if (!re) { re = new RegExp("(" + reStr +")","ig" ); } // iterate through each matched element return this.each( function() { // select all contents of this element $( this ).find("*" ).andSelf().contents() // filter to only text nodes that aren't already highlighted .filter( function () { return this.nodeType === 3 && $( this ).closest("." + hClass ).length === 0; }) // loop through each text node .each( function () { var output; output = this.nodeValue .replace( re,"<" + defaultTagName +" class='" + hClass +"'>$1</" + defaultTagName +">" ); if ( output !== this.nodeValue ) { $( this ).wrap("<p> </p>" ).parent() .html( output ).contents().unwrap(); } }); }); }; $.fn.highlightText.defaultTagName ="span"; })( jQuery ); $("body").highlightText("€","currency-symbol"); $("span.currency-symbol").text("$"); |
。
对于文档中的每个元素,
1 2 3 | $("body *").text(function() { return $(this).text().replace("x","xy"); }); |
我想你可能想得太多了。
我的方法很简单。
用DIV标记将页面括起来:
1 | <!-- you page here --> |
在您的javascript中:
1 2 3 | var html=document.getElementById('mydiv').innerHTML; html = html.replace(/this/g,"that"); document.getElementById('mydiv').innerHTML=html; |
由于您仍将使用jquery,请尝试:
https://github.com/牛仔/jquery-replacetext
那就这么做吧
1 | $("p").replaceText("£","$") |
。
它似乎只能替换文本,而不能与其他元素混淆。
1 | str.replace(/replacetext/g,'actualtext') |
。
这就用
您可以使用:
1 | str.replace(/text/g,"replaced text"); |
号