Java正则表达式:将自定义Hashtag模式与前瞻/后瞻条件相匹配

时间:2015-10-04 04:02:47

标签: java regex

我目前正在学习如何通过尝试匹配简单的Hashtag模式来编写Java中的正则表达式。 Hashtags遵守以下条件:

  1. 以标签开头:#
  2. 必须至少包含1个字母:[a-zA-Z]
  3. 它可以包含类[a-zA-Z0-9 _]
  4. 中的任何字符
  5. 前面不能有班级的字符[a-zA-Z0-9 _]
  6. 基于此,我认为正确的正则表达式是:

    PATTERN = "(?<![a-zA-Z0-9_])#(?=.*[a-zA-Z])[a-zA-Z0-9_]+"
    

    这里我使用前瞻(?=.*[a-zA-Z])来确保条件2成立,并使用lookbehind (?<![a-zA-Z0-9_])来确保条件4成立。我不太确定以+结尾。

    这适用于简单的测试用例,但在复杂的测试用例上失败,例如:

    String text = "####THIS_IS_A_HASHTAG; ;#This_1_2...#12_and_this but not #123  or #this# #or#that";
    

    其中不匹配#THIS_IS_A_HASHTAG#This_1_212_and_this

    有人可以解释我做错了吗?

2 个答案:

答案 0 :(得分:2)

这个先行:

(?=.*[a-zA-Z])
当输入如下时,

可能会产生错误的结果:

####12345...#12_and_this

为您提供2个匹配#12345#12_and_this。根据您的规则,只有第二个应该是有效匹配。

要解决此问题,您可以使用此正则表达式:

(?<![a-zA-Z0-9_])#(?=[0-9_]*[a-zA-Z])[a-zA-Z0-9_]+

前瞻(?=[0-9_]*[a-zA-Z])表示在#之后声明存在一个字母,其中可选择存在数字或下划线。

Here is a regex demo for you

答案 1 :(得分:0)

这个怎么样?

(example here)

String text = "####THIS_IS_A_HASHTAG;;;#This_1_2...#12_and_this ";
String regex = "#[A-Za-z0-9_]+";

Matcher m = Pattern.compile(regex).matcher(text);

while (m.find()) {
  System.out.println(m.group());
}

它看起来符合您所说的标准:

#THIS_IS_A_HASHTAG
#This_1_2
#12_and_this