2016-11-14 75 views
-1

我正在用正则表达式构建一个简单的twitter用户提到查找器。JAVA匹配组

public static Set<String> getMentionedUsers(List<Tweet> tweets) { 
    Set<String> mentionedUsers = new TreeSet<>(); 
    String regex = "(?<=^|(?<=[^a-zA-Z0-9-_\\\\.]))@([A-Za-z][A-Za-z0-9_]+)"; 

    for(Tweet tweet : tweets){ 
     Matcher matcher = Pattern.compile(regex).matcher(tweet.getText().toLowerCase()); 
     if(matcher.find()) { 
      mentionedUsers.add(matcher.group(0)); 
     } 
    } 
    return mentionedUsers; 
} 

而且它未能找到匹配,如果表达式为文本例如结束“@格洛弗告诉我@GREG”它只返回“@格洛弗”。

+0

您是否记住group(0)是您的正则表达式的完整匹配,而group(1)将会是您在正则表达式中定义的第一个捕获组内的内容? –

回答

4

您必须通过单个tweet保持循环与matcher.find(),直到您没有找到任何更多的匹配,您目前只检查一次tweet。

(旁注:你应该编译你的for循环,更好的将是编译的方法之外的外模式)

public static Set<String> getMentionedUsers(List<Tweet> tweets) { 
    Set<String> mentionedUsers = new TreeSet<>(); 
    String regex = "(?<=^|(?<=[^a-zA-Z0-9-_\\\\.]))@([A-Za-z][A-Za-z0-9_]+)"; 

    Pattern p = Pattern.compile(regex); 
    for(Tweet tweet : tweets){ 
     Matcher matcher = p.matcher(tweet.getText().toLowerCase()); 
     while (matcher.find()) { 
      mentionedUsers.add(matcher.group(0)); 
     } 
    } 
    return mentionedUsers; 
} 
+0

男士......我即将发布相同的内容。 –

0

你加入matcher.group(0)Set,看一看,以Java Docs

组零表示整个模式,所以表达式m.group(0)等同于m.group()。

从1所述的捕获组开始,见reference

组号码

捕获组通过计数它们的开口被编号括号 从左到右。在表达式((A)(B(C))),例如,存在 四种这样的基团:

1((A)(B(C)))

2(A)

3(B(C))

4(C)

组零始终代表整个表达式。

捕获组的名称是这样命名的,因为在匹配期间,保存与匹配这个组的输入序列的每个 子序列。 捕获的子序列可以在后面的表达式中通过反向引用使用,并且也可以在匹配操作完成后从匹配器中检索。