[英]Javascript Regexp - Match string pattern except if string is inside specified tag
I am trying to replace all occurences of ???some.text.and.dots??? 我试图替换所有出现的??? some.text.and.dots ??? in a html page to add a link on it.
在html页面中添加链接。 I've built this regexp that does it :
我已经构建了这个正则表达式:
\\?\\?\\?([a-z0-9.]*)\\?\\?\\? \\?\\?\\?([A-Z0-9] *)\\?\\?\\?
However, I would like to exclude any result that is inside a link : "<a ...> ... MY PATTERN ... </a>", and I am a little stuck as to how to do that, all my attempts have failed for now. 但是,我想排除链接中的任何结果:“<a ...> ...我的模式... </a>”,我对如何做到这一点有点困惑,所有我的尝试暂时失败了。
It's not really clear what kind of "HTML" you are working on. 你正在研究什么样的“HTML”并不是很清楚。 If it is HTML code , something from an Ajax request maybe, then you can use a regular expression;
如果它是HTML 代码 ,可能来自Ajax请求,那么你可以使用正则表达式; matching both a link or the pattern, and then work out what to do in a callback:
匹配链接或模式,然后找出在回调中要做的事情:
var html = document.body.innerHTML;
html = html.replace(/(<a\s.*?>.*?<\/a>)|(\?\?\?([a-z0-9.]*)\?\?\?)/g,
function ( a, b, c, d ) {
return ( a[0] == '<' ) ? a : '<a href="#">' + d + '</a>';
});
context.innerHTML = html;
Conveniently, replace()
can take a callback function as a replacement generator rather than a simple string. 方便的是,
replace()
可以将回调函数作为替换生成器而不是简单的字符串。
If you are working on a live DOM tree, however, you might want to respect events on nodes and not simply reset the innerHTML
. 但是,如果您正在处理实时DOM树,则可能需要尊重节点上的事件而不是简单地重置
innerHTML
。 You'll need a bit more primitive approach for that: 你需要一个更原始的方法:
// returns all childnodes of type text that do not have A as parent
function walker ( node ) {
var nodes = [];
for (var c, i = 0; c = node.childNodes[i]; i++) {
if ( c.nodeType === 1 && c.tagName !== 'A' ) {
nodes = nodes.concat( arguments.callee( c ) );
}
else if ( c.nodeType === 3 ) {
nodes.push( c );
}
}
return nodes;
}
var textNodes = walker( document.body );
for (var i = 0; i < textNodes.length; i++) {
// create an array of strings separating the pattern
var m = textNodes[i].nodeValue.split( /(\?\?\?([a-z0-9.]*)\?\?\?)/ );
if ( m.length > 1 ) {
for (var j=0; j<m.length; j++) {
var t, parent = textNodes[i].parentNode;
// create a link for any occurence of the pattern
if ( /^\?\?\?([a-z0-9.]*)\?\?\?$/.test( m[j] ) ) {
var a = document.createElement( 'a' );
a.href = "#";
a.innerHTML = RegExp.$1; // m[j] if you don't want to crop the ???'s
parent.insertBefore( a, textNodes[i] );
t = document.createTextNode( ' ' ); // whitespace padding
}
else {
t = document.createTextNode( m[j] );
}
parent.insertBefore( t, textNodes[i] );
}
// remove original text node
parent.removeChild( textNodes[i] );
}
}
This method only touches textnodes, and then only those that match the pattern. 此方法仅触及文本节点,然后仅触摸与模式匹配的文本节点。
JavaScript doesn't inherently support look-behind. JavaScript本身并不支持后视。 In order to do this, you'd need to run .match() and then for each of your matches, you'd need to do matches on your tags (such as /<a\\s+.*?>/ being immediately before your match and then </a> after your match).
为了做到这一点,你需要运行.match(),然后对于你的每个匹配,你需要在你的标签上做匹配(比如/<a \\ s +。*你的比赛,然后在你的比赛后</a>。
Good luck!! 祝好运!!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.