我是一个正则表达式新手,我不知道如何编写一个正则表达式来“匹配”任何重复的连续单词,例如:
春天的巴黎。
并不是说有关系。
你笑什么?我的正则表达式那么糟糕吗?
是否有一个正则表达式可以匹配上面所有的粗体字符串?
我是一个正则表达式新手,我不知道如何编写一个正则表达式来“匹配”任何重复的连续单词,例如:
春天的巴黎。
并不是说有关系。
你笑什么?我的正则表达式那么糟糕吗?
是否有一个正则表达式可以匹配上面所有的粗体字符串?
我相信这个正则表达式可以处理更多的情况:
/(\b\S+\b)\s+\b\1\b/
可以在这里找到很好的测试字符串选择:http: //callumacrae.github.com/regex-tuesday/challenge1.html
下面的表达式应该可以正常工作以查找任意数量的连续单词。匹配可以不区分大小写。
String regex = "\\b(\\w+)(\\s+\\1\\b)*";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(input);
// Check for subsequences of input that match the compiled pattern
while (m.find()) {
input = input.replaceAll(m.group(0), m.group(1));
}
示例输入:再见再见 GooDbYe
样本输出:再见
解释:
正则表达式:
\b :单词边界的开始
\w+ : 任意数量的单词字符
(\s+\1\b)* :任意数量的空格后跟单词,匹配前一个单词并结束单词边界。用 * 包裹的整件事有助于找到不止一个重复。
分组:
m.group(0) :应包含上述情况下的匹配组 Goodbye goodbye GooDbYe
m.group(1) :应包含上述情况下匹配模式的第一个单词 Goodbye
Replace 方法将所有连续匹配的单词替换为单词的第一个实例。
试试下面的 RE
()* 再次重复
public static void main(String[] args) {
String regex = "\\b(\\w+)(\\b\\W+\\b\\1\\b)*";// "/* Write a RegEx matching repeated words here. */";
Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE/* Insert the correct Pattern flag here.*/);
Scanner in = new Scanner(System.in);
int numSentences = Integer.parseInt(in.nextLine());
while (numSentences-- > 0) {
String input = in.nextLine();
Matcher m = p.matcher(input);
// Check for subsequences of input that match the compiled pattern
while (m.find()) {
input = input.replaceAll(m.group(0),m.group(1));
}
// Prints the modified sentence.
System.out.println(input);
}
in.close();
}
广泛使用的 PCRE 库可以处理这种情况(但是,您不会使用符合 POSIX 的正则表达式引擎来实现相同的效果):
(\b\w+\b)\W+\1
不,那是不规则的语法。您可能可以使用特定于引擎/语言的正则表达式,但没有通用的正则表达式可以做到这一点。
这是我用来删除 twitch 机器人中重复短语的正则表达式:
(\S+\s*)\1{2,}
(\S+\s*)
查找不是空格的任何字符串,后跟空格。
\1{2,}
然后在要匹配的字符串中查找该短语的 2 个以上实例。如果有 3 个相同的短语,则匹配。
这是一个多次捕获多个单词的方法:
(\b\w+\b)(\s+\1)+
Javascript: The Good Parts 中的示例可用于执行此操作:
var doubled_words = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+\1(?:\s|$)/gi;
\b 使用 \w 作为单词边界,其中 \w 等价于 [0-9A-Z_a-z]。如果您不介意这种限制,那么接受的答案就可以了。
由于一些开发人员来到此页面寻找一种解决方案,该解决方案不仅可以消除重复的连续非空白子字符串,而且可以消除三次及以上,因此我将展示适应的模式。
模式:(/(\b\S+)(?:\s+\1\b)+/
模式演示)
替换:($1
用捕获组#1替换完整字符串匹配)
此模式贪婪地匹配“整个”非空白子字符串,然后需要一个或多个匹配子字符串的副本,这些副本可能由一个或多个空白字符(空格、制表符、换行符等)分隔。
具体来说:
\b
(单词边界)字符对于确保部分单词不匹配至关重要。+
非捕获组上的(一个或多个量词)比*
因为*
会“打扰”正则表达式引擎来捕获和替换单例事件更合适——这是一种浪费的模式设计。*请注意,如果您正在处理带有标点符号的句子或输入字符串,则需要进一步完善该模式。
这个表达式(灵感来自上面的 Mike)似乎捕捉到了所有重复、三次等,包括字符串末尾的那些,而其他大多数都没有:
/(^|\s+)(\S+)(($|\s+)\2)+/g, "$1$2")
我知道要求仅匹配重复项的问题,但一式三份只是彼此相邻的 2 个重复项:)
首先,我(^|\s+)
确保它以一个完整的单词开头,否则“child's steak”会转到“child'steak”(“s”会匹配)。然后,它匹配所有完整(\b\S+\b)
的单词 ( ),后跟字符串结尾 ( $
) 或多个空格 ( \s+
),整个重复不止一次。
我像这样尝试过,效果很好:
var s = "here here here here is ahi-ahi ahi-ahi ahi-ahi joe's joe's joe's joe's joe's the result result result";
print( s.replace( /(\b\S+\b)(($|\s+)\1)+/g, "$1"))
--> here is ahi-ahi joe's the result
试试这个适用于所有重复单词情况的正则表达式:
\b(\w+)\s+\1(?:\s+\1)*\b
如果您想要不区分大小写检查重复单词,请使用此选项。
(?i)\\b(\\w+)\\s+\\1\\b