【问题标题】:Java String Regex with multi-level conditions具有多级条件的 Java 字符串正则表达式
【发布时间】:2018-08-13 19:06:31
【问题描述】:

我想在一个字符串中找到一个字符串,这是我的场景:

String toMatch = "ABC";
String matchIn = "ABC*FED";

matchIn 的其他变体:

matchIn = "ABC";
matchIn = "ASD*ABC";
matchIn = "JULY*ABC*RTEW";

我想出了这个正则表达式,但它显然不起作用:

matchIn.matches(".*(\\*)?" + toMatch + "(\\*)?.*");

这里的问题是我不知道如何查找 "*" 只有当它后面跟着另一个词时。这样,它只是匹配所有内容,例如, toMatch="ABCDEF" 在不应该的时候返回 true!

【问题讨论】:

标签: java regex string


【解决方案1】:

你可以使用像这样的正则表达式

(?<=^|\*)ABC(?=$|\*)

或者

(?<![^*])ABC(?![^*])

请参阅regex demo

详情

  • (?&lt;=^|\*) - 正向后视,要求字符串开头的位置 (^) 或 (|) * 符号立即出现在当前位置的左侧(注意 (?&lt;![^*]) 是一个等效的 negative 后向构造,它匹配任何不紧跟在任何字符之前但* 的位置,因此它的含义与(?&lt;=^|\*) 相同)
  • ABC - 文字字符串模式 (ABC)
  • (?=$|\*) - 一个正向前瞻,紧挨当前位置的右侧(即在 ABC 之后),需要字符串结尾 ($) 或 * 字符(相当于负前瞻(?&lt;![^*])ABC(?![^*]))。

请注意,带有负面lookbehinds的变化更有效,因为这些lookarounds内部没有交替(它比使用它成本更高)。

使用.find() 来检查部分匹配(带有.* 的正则表达式效率太低):

List<String> strs = Arrays.asList("ABC", "ASD*ABC", "JULY*ABC*RTEW", "ASDABC");
Pattern p = Pattern.compile("(?<=^|\\*)ABC(?=$|\\*)");
for (String str : strs) {
    Matcher m = p.matcher(str);
    System.out.println("\"" + str + "\" => " + m.find());
}

输出:

"ABC" => true
"ASD*ABC" => true
"JULY*ABC*RTEW" => true
"ASDABC" => false

请参阅Java demo

【讨论】:

  • 谢谢,你知道为什么它不能与 String.matches 一起工作吗?
  • @nullpointer 因为String#matches() 需要完整的字符串匹配。如果您寻求部分匹配,请不要使用它。
  • ^ 表示字符串的开头,$ 表示字符串的结尾,对吗?我不明白 ?,
  • @nullpointer 抱歉,其他用户问了我一些问题,我现在已经添加了详细信息。
  • @nullpointer 注意:如果我正确理解你想要什么,str.startsWith("ABC") || str.indexOf("*ABC") &gt; 0 也可以完成这项工作并且更具可读性。这取决于您提出问题是为了了解正则表达式,还是打算在生产中使用代码。
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
  • 2014-04-28
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多