Java正则表达式:如何选择以特定字母开头并且长度为x个字符的单词?

Enz*_*zio 1 java regex

这是我编写的代码,它选择从 A 开始的所有名称:

String longString = "Amal Kamal Jamal Amitha Farook Amani Tom Adele George Ariana";
String pattern = "(?i)(\\s|^)[a][A-Za-z]+(\\s|$)";
Pattern checkRegex = Pattern.compile(pattern);
Matcher regexMatcher = checkRegex.matcher(longString);
while (regexMatcher.find()) {
    System.out.println(regexMatcher.start() + " : " + regexMatcher.group());
}
Run Code Online (Sandbox Code Playgroud)

输出符合预期

0 : Amal 
16 :  Amitha 
30 :  Amani 
40 :  Adele 
53 :  Ariana
Run Code Online (Sandbox Code Playgroud)

现在我想选择长度至少为 5 个字符的名称。所以预期输出是:Amitha、Adele、Ariana。

当我输入此内容时,仅返回 Ariana。我不明白为什么。

String pattern = "(?i)(\\s|^)[a][A-Za-z]+(\\s|$){5,}";
Run Code Online (Sandbox Code Playgroud)

输出

53 :  Ariana
Run Code Online (Sandbox Code Playgroud)

如果我在整个表达式周围加上括号(表示该表达式应该有 5 个字符长),那么输出什么也没有

String pattern = "(?i)((\\s|^)[a][A-Za-z]+(\\s|$)){5,}";
Run Code Online (Sandbox Code Playgroud)

正确的写法是什么?

Wik*_*żew 5

(\\s|$)当你需要量化时你就量化了[a-zA-Z]。因此,您只匹配单词后有 5 个或更多空格或 5 个或更多字符串结尾(当然没有意义)的文本。另外,您需要使用{4,}as[a]已经匹配 1 个字母。

使用此正则表达式来解决问题(尽管它不是最好的,请参阅下面的原因):

(?i)(\s|^)a[a-z]{4,}(\s|$)
Run Code Online (Sandbox Code Playgroud)

细节

  • (?i)- 不区分大小写的修饰符
  • (\s|^)- 空格或字符串的开头
  • a -aA字母
  • [a-z]{4,}- 任意 4 个或更多 ASCII 字母
  • (\s|$)- 空格或字符串结尾(注意:空格将被消耗,连续匹配的单词将无法正确处理)。

您可以使用"(?i)(?<!\\S)a[a-z]{4,}(?!\\S)"模式来确保匹配空格或字符串位置的开头/结尾之间的单词。

或者,使用单词边界 - "(?i)\\ba[a-z]{4,}\\b"

请参阅Java 在线演示

String longString = "Amal Kamal Jamal Amitha Farook Amani Tom Adele George Ariana";
String pattern = "(?i)(?<!\\S)a[a-z]{4,}(?!\\S)";
Pattern checkRegex = Pattern.compile(pattern);
Matcher regexMatcher = checkRegex.matcher(longString);
while (regexMatcher.find()) {
    System.out.println(regexMatcher.start() + " : " + regexMatcher.group());
}
Run Code Online (Sandbox Code Playgroud)

结果:

17 : Amitha
31 : Amani
41 : Adele
54 : Ariana
Run Code Online (Sandbox Code Playgroud)