用于匹配重复子串的单个js正则表达式?

jon*_*nny 5 javascript regex string

说我有一个字符串,如:

where is mummy where is daddy
Run Code Online (Sandbox Code Playgroud)

我想用空字符串替换任何一组重复的子字符串 - 所以在这种情况下where,is将删除和元素,结果字符串将是:

mummy daddy
Run Code Online (Sandbox Code Playgroud)

我想知道是否有任何单一的正则表达式可以实现这一点.我试过的正则表达式(不起作用)如下所示:

/(\w+)(?=.*)\1/gi
Run Code Online (Sandbox Code Playgroud)

在第一个捕获组是任何字符集的情况下,第二个是对任何字符集的正面观察(为了防止这些字符包含在结果中),然后\1是对第一个匹配的子字符串的反向引用.

任何帮助都会很棒.提前致谢!

Wik*_*żew 7

你的正则表达式不起作用,因为\w+它不受字边界限制,并且\1反向引用试图在"原始"单词之后匹配,这几乎不是真的.

你需要首先得到dupes的单词,然后构建一个RegExp,将它们全部与可选的空格(或标点符号等)相匹配 - 稍后调整模式并用空字符串替换:

var re = /(\b\w+\b)(?=.*\b\1\b)/gi;                  // Get the repeated whole words
var str = 'where is mummy where is daddy';
var patts = str.match(re);                       // Collect the matched repeated words
var res = str.replace(RegExp("\\s*\\b(?:" + patts.join("|") +")\\b", "gi"), ""); //  Build the pattern for replacing all found words
document.body.innerHTML = res;
Run Code Online (Sandbox Code Playgroud)

第一种模式是 (\b\w+\b)(?=.*\b\1\b):

  • (\b\w+\b)- 匹配并捕获由[A-Za-z0-9_]字符组成的整个单词
  • (?=.*\b\1\b) - 确保捕获到组1中的值重复到当前位置右侧的某个位置(不一定在单词后面).如果字符串是多行,请使用[\s\S]而不是点.为了确保我们原来的匹配和重复数据删除的话整个单词,\b单词的边界应该围绕这两个被使用\w+\1.

第二种模式每次都会有所不同,但在当前情况下,它将是/\s*\b(?:where|is)\b/gi:

  • \s* - 零或更多whitepsace
  • \b(?:where|is)\b- 来自交替组的整个单词(?:...|...):where或者is(由于/i修饰符而不区分大小写).

  • 很好的答案!不过,在使用您的代码时,我偶然发现了一个令人惊讶的问题。似乎对单词边界的检查不是第一个捕获组的一部分。因此,如果您在字符串“where is my mummy where is daddy”上使用它,则单词“my”也会被删除,因为它出现在“mummy”中。为避免误报,您必须再次添加对第一个捕获组重复周围的单词边界的检查 (var re = /(\b\w+\b)(?=.*\b\1\b)/gi )。 (2认同)