Javascript Regexp仅搜索/替换文本,而不是在HTML属性中
我正在使用JavaScript做一些正则表达式。考虑到我使用的是格式良好的源代码,我希望删除[,.]之前的所有空格,并在[,.]之后只保留一个空格,除了[,.]是数字的一部分。因此,我使用:Javascript Regexp仅搜索/替换文本,而不是在HTML属性中,javascript,html,regex,Javascript,Html,Regex,我正在使用JavaScript做一些正则表达式。考虑到我使用的是格式良好的源代码,我希望删除[,.]之前的所有空格,并在[,.]之后只保留一个空格,除了[,.]是数字的一部分。因此,我使用: text = text.replace(/ *(,|\.) *([^ 0-9])/g, '$1 $2'); 问题是,这也会替换html标记属性中的文本。例如,我的文本(始终用标记包装): 谢谢 Html不是“常规语言”,因此regex不是解析它的最佳工具。您可能更适合使用正则表达式,然后应用正则表达式来处
text = text.replace(/ *(,|\.) *([^ 0-9])/g, '$1 $2');
问题是,这也会替换html标记属性中的文本。例如,我的文本(始终用标记包装):
谢谢 Html不是“常规语言”,因此regex不是解析它的最佳工具。您可能更适合使用正则表达式,然后应用正则表达式来处理值
享受吧 。如果您知道您的HTML格式良好,请使用HTML/XML解析器。否则,请先在Tidy中运行它,然后使用XML解析器。不要试图重写表达式来完成此操作。你不会成功的,而且几乎肯定会忘记一些角落案例。在最好的情况下,这将导致严重的错误,在最坏的情况下,您将引入安全问题
相反,当您已经在使用JavaScript并拥有格式良好的代码时,请使用真正的XML解析器在文本节点上循环,并仅对它们应用正则表达式。如上所述,HTML不是一种常规语言,因此无法使用正则表达式进行解析 你必须递归地这样做;我建议对DOM对象进行爬网 试试这样的
function regexReplaceInnerText(curr_element) {
if (curr_element.childNodes.length <= 0) { // termination case:
// no children; this is a "leaf node"
if (curr_element.nodeName == "#text" || curr_element.nodeType == 3) { // node is text; not an empty tag like <br />
if (curr_element.data.replace(/^\s*|\s*$/g, '') != "") { // node isn't just white space
// (you can skip this check if you want)
var text = curr_element.data;
text = text.replace(/ *(,|\.) *([^ 0-9])/g, '$1 $2');
curr_element.data = text;
}
}
} else {
// recursive case:
// this isn't a leaf node, so we iterate over all children and recurse
for (var i = 0; curr_element.childNodes[i]; i++) {
regexReplaceInnerText(curr_element.childNodes[i]);
}
}
}
// then get the element whose children's text nodes you want to be regex'd
regexReplaceInnerText(document.getElementsByTagName("body")[0]);
// or if you don't want to do the whole document...
regexReplaceInnerText(document.getElementById("ElementToRegEx"));
函数regexReplaceInnerText(curr_元素){
如果(curr_element.childNodes.length如果可以通过DOM访问该文本,则可以执行以下操作:
function fixPunctuation(elem) {
// check if parameter is a an ELEMENT_NODE
if (!(elem instanceof Node) || elem.nodeType !== Node.ELEMENT_NODE) return;
var children = elem.childNodes, node;
// iterate the child nodes of the element node
for (var i=0; children[i]; ++i) {
node = children[i];
// check the child’s node type
switch (node.nodeType) {
case Node.ELEMENT_NODE:
// call fixPunctuation if it’s also an ELEMENT_NODE
fixPunctuation(node);
break;
case Node.TEXT_NODE:
// fix punctuation if it’s a TEXT_NODE
node.nodeValue = node.nodeValue.replace(/ *(,|\.) *([^ 0-9])/g, '$1 $2');
break;
}
}
}
现在只需将DOM节点传递给该函数,如下所示:
fixPunctuation(document.body);
fixPunctuation(document.getElementById("foobar"));
您可以使用前瞻来确保匹配不会发生在标记中:
text = text.replace(/(?![^<>]*>) *([.,]) *([^ \d])/g, '$1 $2');
text=text.replace(/(?![^]*>)*([,])*([^\d])/g,“$1$2”);
通常的警告适用于CDATA节、SGML注释、脚本元素和属性值中的尖括号。但我怀疑您真正的问题将来自“普通”的变幻莫测文本;HTML甚至不在同一类中。:D这不是Regex的擅长之处,因为HTML不是一种常规语言。有太多的范围/嵌套/上下文。文本可以通过DOM访问吗?是的,我想,即使我没有尝试过。我想将其作为CKEditor插件编写,这就是为什么我说“格式良好”(嗯,我是指XHTML)。我有源代码,但我想我可以得到作为DOM元素的is。你可能是说“不要用正则表达式解析HTML”,而不是相反。。)@Scytale-他只是在彻底研究;但是,只要我们在这个主题上,人们也不应该用HTML解析正则表达式!;@Scytale@Richard hahaha我甚至没有看到。我的坏习惯是:)你把函数名fixparcination
拼错了几次;)那是一个Java HTML解析器。他想这样做,我n JavaScript。我不工作。“测试,和”应该变成“测试,和”。我也在考虑寻找,但我没有得到它。类似于寻找“…>任何东西,但<(要查找/替换的文本)”。我认为[^]*上面的部分不是必需的。当我测试它时,里面有更多的星号,但它们消失了。现在试试。我正在使用另一个解决方案。但是这个更好:)谢谢。
fixPunctuation(document.body);
fixPunctuation(document.getElementById("foobar"));
text = text.replace(/(?![^<>]*>) *([.,]) *([^ \d])/g, '$1 $2');