【问题标题】:Java Regular Expression: matching a customized Hashtag pattern with a lookahead/lookbehind conditionJava 正则表达式:将定制的 Hashtag 模式与前瞻/后瞻条件匹配
【发布时间】:2015-10-05 06:03:47
【问题描述】:

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

  1. 它以标签开头:#
  2. 必须至少包含 1 个字母:[a-zA-Z]
  3. 它可以包含 [a-zA-Z0-9_] 类中的任何字符
  4. 前面不能有 [a-zA-Z0-9_] 类的字符

基于此,我认为正确的正则表达式是:

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

在这里,我使用前瞻 (?=.*[a-zA-Z]) 来确保条件 2 成立,并使用后瞻 (?&lt;![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

谁能解释我做错了什么?

【问题讨论】:

  • 你想如何匹配这个?运行这会导致 RE 匹配所有三个。

标签: java regex


【解决方案1】:

这个前瞻:

(?=.*[a-zA-Z])

输入如下情况可能会产生错误的结果:

####12345...#12_and_this

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

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

(?<![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

【讨论】:

    【解决方案2】:

    这个怎么样?

    (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
    

    【讨论】:

    • 你是对的。您提出的正则表达式通过了我昨天发布的示例,但它不能确保主题标签至少包含 1 个字母(这是我列出但未包含在示例中的条件)。我已经相应地更新了示例。对不起!
    猜你喜欢
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    相关资源
    最近更新 更多