正则表达式匹配不被其他字符包围的精确单词

3

我正在尝试创建一个正则表达式来匹配一组单词。

例如,如果我要匹配一组词 - American Tea

那么在字符串 American Tea is awesome. Do you like American Tea? love WowAmerican Tea #American Tea 中,只有两个匹配项,

'American Tea is awesome. Do you like American Tea? love WowAmerican Tea #American Tea'

所以,我想只进行完全匹配。

我尝试了一些方法,但是没有得到正确的正则表达式:( 如果有人可以帮忙或指导我方向,将非常有帮助。

检查这个

'American Tea lalalal qwqwqw American Tea sdsdsd #American Tea'.match(/(?:^|\s)(American Tea)(?=\s|$)/g)

它的结果是["American Tea", " American Tea"]

我不想在第二次匹配中有空格,我希望匹配结果为["American Tea", "American Tea"]

(第二个American Tea前面没有空格)


所以,你想要3个匹配还是2个?你说的空间问题是什么?前导空格?展示代码,这样就更清楚你在做什么了。一般来说,在JS中,当你需要同时使用lookbehind和lookahead时,你必须使用捕获。就像这里的 (^|\s)(American Tea)(?=$|\s) - Wiktor Stribiżew
我所拥有的是 /(?:^|\s)(American Tea)(?=\s|$)/g,但它存在空格问题。 - ghostCoder
编辑了问题以添加更多细节。 - ghostCoder
@stribizhev 是的,我需要索引,因为我需要用某些内容替换匹配的单词以突出显示已输入的单词。 - ghostCoder
让我们在聊天室中继续讨论此事。 - Wiktor Stribiżew
显示剩余3条评论
4个回答

2

使用 .replace() 方法,让你玩得开心,又能有所收益。

/(?:^|\s)(american tea)/ig

如果您想考虑前缀和后缀: https://regex101.com/r/qB0uO2/1
/(?:^|\s)(american tea)(?:\W|$)/ig 

点击这里查看与正则表达式相关的内容。

JSBIN示例

var str = "American Tea is awesome. Do you like American Tea? love WowAmerican Tea #American Tea";

str.replace(/(?:^|\s)(american tea)(?:\W|$)/ig, function(i, m){
  console.log(m);
});

//"American Tea"
//"American Tea"

编辑:

以上代码只返回匹配的内容,如果你想保留捕获和匹配的前缀和后缀,请使用捕获组来实现:

var str = "American Tea is awesome. Do you like American Tea? love WowAmerican Tea #American Tea";

var newStr = str.replace(/(^|\s)(american tea)(\W|$)/ig, function(im, p1, p2, p3){
  return  p1 +"<b>"+ p2 +"</b>"+ p3; // p1 and p3 will help preserve the pref/suffix
});

document.getElementById("result").innerHTML = newStr;
<div id="result"></div>

关于 parts 的部分:

  • p1 是第一个匹配组(任意前缀)
  • p2 是第二个匹配组("American Tea" 单词)
  • p3 是第三个匹配组(任意后缀)

@ghostCoder 请查看 jsbin 示例。结果完全正确。 - Roko C. Buljan
第二个“American Tea”旁边的空格也被替换了。 - ghostCoder
1
@ghostCoder 请看一下这个链接:http://jsbin.com/cilosi/1/edit?html,css,js,console,output 看到控制台了吗?我没有发现任何错误。问题出在你那里,而不是我的回答 :) - Roko C. Buljan
@RokoC.Buljan,你能否请检查一下这个链接https://jsfiddle.net/hy812kgr/。这个链接与你提供的那个表达式相同。 - ghostCoder
我想将文本“American Tea”替换为“wow”,但不要删除单词旁边的空格。这就是我在尝试实现的目标。 - ghostCoder
显示剩余6条评论

0
阅读评论后,我意识到正则表达式可能不是最好的解决方案。然而,有趣的是,你如何规避Javascript不支持正向后瞻的事实,这将使此任务变得容易。
如果JS有(?<=...)结构,那么您只需使用正向后瞻和正向前瞻,并列出所有您想要允许在美国茶左侧和右侧的字符即可。所以我们想要的是这样的东西:
(?<=\s|\.|,|:|;|\?|\!|^)American Tea(?=\s|\.|,|:|;|\?|\!|$)

在左边,您可以允许列出的任何字符和字符串的开头^。在右边,您允许相同的字符和字符串的结尾$。

但是Javascript没有(?<=...)结构。因此,我们需要有点创意:

(?=(\s|\.|,|:|;|\?|\!|^))\1(American Tea)(?=\s|\.|,|:|;|\?|\!|$)

这个正则表达式将正向后瞻替换为正向前瞻。然后,它使用 \1 匹配在前瞻中找到的任何内容,最终“American Tea”将被捕获在第一个捕获组中。

演示:https://regex101.com/r/qX9qR3/3


0

你不需要正则表达式来匹配单词。

我知道一个非常简洁的CoffeeScript片段:

wordList = ["coffeescript", "eko", "talking", "play framework", "and stuff", "falsy"]
tweet = "This is an example tweet talking about javascript and stuff."

wordList.some (word) -> ~tweet.indexOf word # returns true

这将编译成以下 JavaScript 代码:

var tweet, wordList;

wordList = ["coffeescript", "eko", "talking", "play framework", "and stuff", "falsy"];

tweet = "This is an example tweet talking about javascript and stuff.";

wordList.some(function(word) { // returns true
  return ~tweet.indexOf(word); 
});

在 CoffeeScript 中, ~ 不是一个特殊的运算符,它只是一个很酷的技巧。它是按位取反操作符,可以翻转其操作数的位。实际上,它等同于 -x-1。在这里,它的作用是我们想要检查索引是否大于-1,而 -(-1)-1 == 0 等于 false。

如果你想要匹配的单词,使用 :

wordList.filter (word) -> ~tweet.indexOf word # returns : [ "talking", "and stuff" ]

或者在JS中相同:

wordList.filter(function(word) { // returns : [ "talking", "and stuff" ]
  return ~tweet.indexOf(word);
});

这段代码允许整词搜索(和/或替换)吗?我在这段代码中没有看到这个功能。 - Wiktor Stribiżew
什么是整词搜索?这段代码难道不是匹配整个单词(甚至可以是以空格分隔的,比如“美国茶”)吗?不确定你在这里指的是什么。 - Jeremy Thille

0

虽然Jeremy当然是正确的,但我认为你的问题比你编造的例子中显示的更复杂。

从看起来的情况来看,您正在尝试使用常规RegEx单词边界,但除了将“#”视为单词字符之外。在这种情况下,您可以像这样做:(其中\b表示“单词边界”)

(^|[^#])\bAmerican Tea\b

或者,如果你只是想列出你认为的非单词字符,可以像这样做来模拟单词边界:

(^|[^A-Za-z])American Tea($|[^A-Za-z])

你可以在 http://www.regexr.com/ 玩耍。


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