JavaScript正则表达式:未跟随特定字符且未在特定字符之前的单词。

8

我猜我对正则表达式不是很擅长,所以这就是我的问题(我确定它很容易解决,但不知何故我似乎找不到答案)

var word = "aaa";
text = text.replace( new RegExp(word, "g"),
                     "<span style='background-color: yellow'>"+word+"</span>");

这在大多数情况下都有效。

我想要的是仅当单词后面不跟随字符/并且前面没有字符"时,正则表达式才能生效。

3个回答

15
您需要使用负向前瞻。
正则表达式: '[^"]' + word + '(?!/)' 编辑:尽管这似乎不重要,因为您避免了“向后查找”,但Rohit注意到我没有注意到的一些内容。您将需要捕获 [^\"] 并将其包含在替换中,以便它不会被丢弃。 对于正向前瞻,这是不必要的,因为正向前瞻根据定义不包含在捕获中。

非常感谢。所以,如果我也不希望它以字符“\”开头,我应该将其设置为“(?!\)” + 单词 + “(?!/)”。 - MirrorMirror
如果您想确保“双引号”不在单词之前出现,您需要使用负回顾后断言。因此,您需要使用(?<!\") + word + (?!\/)。请查看此链接,这是我学习如何使用它们的地方:http://www.regular-expressions.info/lookaround.html。 - Michael
15
JavaScript不支持后顾断言。 - Rohit Jain
确实它不能往后看。我通过检查两个字符来解决了这个问题,因为如果斜杠后面还有数字,它就不应该找到它,所以不需要往后看。解决方案:word+"(?!/[0-9])", "gi"。你发布的 [^"] 会破坏事情。 - MirrorMirror
1
'[^"]' + word + '(?!/)'就足够了。 - nhahtdh
显示剩余2条评论

4
您可以使用这个正则表达式: -
'([^"])' + word + '(?!/)'

将其替换为-"$1g"

请注意,JavaScript不支持向后查找。因此,您需要捕获前一个字符并确保它不是",使用否定字符类。

请参见演示:http://fiddle.re/zdjt


如果匹配在行的开头或结尾,这将失败。也许问题可以提到这是否重要。 - tripleee

0

首先,这个问题可以解释为:

  1. 匹配未前置未后置的单词"aaaaaa/ 应该匹配,与 "aaa/ 相同),以及
  2. 匹配未前置未后置的带有某些字符的单词"aaaaaa/ 不应该匹配,而 "aaa/ 应该匹配)。

如果您正在使用支持ECMAScript 2018的JavaScript环境,则可以使用后行解决方案:

const word = 'aaa',                     // Word to find
    left = '"',                         // Left-hand negative marker
    right = '/',                        // Right-hand negative marker
    text = 'aaa aaa/ "aaa "aaa/ aaaaa'; // Test string

// Relace any 'word' that does not start with " OR does not end with /
var regex = new RegExp(String.raw`\b(?<!${left})${word}\b(?!${right})`, 'g')
console.log( text.replace(regex, "<span style='background-color: yellow'>$&</span>") );
// => <span style='background-color: yellow'>aaa</span> aaa/ "aaa "aaa/ aaaaa

// Replace any 'word' that does not start with " AND does not end with /
var regex = new RegExp(String.raw`\b${word}\b(?!(?<=${left}${word})${right})`, 'g')
console.log( text.replace(regex, "<span style='background-color: yellow'>$&</span>") );
// => <span style='background-color: yellow'>aaa</span> <span style='background-color: yellow'>aaa</span>/ "<span style='background-color: yellow'>aaa</span> "aaa/ aaaaa

如果你使用的 JavaScript 环境不支持ECMAScript 2018,可以使用

var word = 'aaa',                       // Word to find
    left = '"',                         // Left-hand negative marker
    right = '/',                        // Right-hand negative marker
    text = 'aaa aaa/ "aaa "aaa/ aaaaa'; // Test string

// Relace any 'word' that does not start with " OR does not end with /, one match expected
var regex = new RegExp("([^" + left + "\\w]|^)(" + word + ")\\b(?!" + right + ")", 'g')
console.log( text.replace(regex, "$1<span style='background-color: yellow'>$2</span>") );
// => <span style='background-color: yellow'>aaa</span> aaa/ "aaa "aaa/ aaaaa

// Same as above, but in case "left" is a sequence of chars, not a single char, or a longer pattern:
var regex = new RegExp("(" + left + ")?\\b(" + word + ")\\b(?!" + right + ")", 'g')
console.log( text.replace(regex, function(x,g,gg) { return g ? x : "<span style='background-color: yellow'>" + gg + "</span>";}) );
// => <span style='background-color: yellow'>aaa</span> aaa/ "aaa "aaa/ aaaaa

// Replace any 'word' that does not start with " AND does not end with /, three matches expected
var regex = new RegExp("(" + left + word + right + ")|\\b" + word + "\\b", 'g')
console.log( text.replace(regex, function(x, g) { return g || "<span style='background-color: yellow'>" + x + "</span>";}) );
// => <span style='background-color: yellow'>aaa</span> <span style='background-color: yellow'>aaa</span>/ "<span style='background-color: yellow'>aaa</span> "aaa/ aaaaa

注意:

  • 我在这里使用整词匹配,通过 \b 单词边界(以及其中一个解决方法中否定字符类中的 \w 构造)
  • 如果 rightleft 字符/字符串包含特殊的正则表达式元字符,请记得 在将其用作正则表达式的一部分之前对它们进行转义
  • 相同的转义需求可能也会出现在 word 变量中,但在那种情况下,如果 word 以特殊的正则表达式元字符开头或/和结尾,则单词边界 (\b) 将不再起作用,您需要使用 自适应/动态单词边界

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接