【问题标题】:regular expression to match string of characters only if it is not followed by a specific character正则表达式仅在字符串后面没有特定字符时才匹配字符串
【发布时间】:2012-11-16 12:15:52
【问题描述】:

我需要一个正则表达式,它仅在字符串后面没有正斜杠 (/) 字符并且我想匹配整个字符串时才匹配。

例如下面的字符串应该匹配

/Raj/details/002-542545-1145457

但不是这个

/Raj/details/002-542545-1145457/show

我尝试使用Negative Lookahead 来实现this answer 指定的目标。

我的代码是这样的。

pattern = Pattern.compile("/.*/details/(?!.*/)");
matcher = pattern.matcher(text);
if(matcher.matches()) {
  System.out.println("success");
} else {
System.out.println("failure");
}

它正在失败。但是如果我使用matcher.find() 那么它就成功了。

请帮助我理解为什么它不匹配以及实现此目的的正则表达式?

【问题讨论】:

  • 问题很不清楚..你只想匹配那些不以 / 结尾的字符串,那么 y 是你的第二个示例无效
  • 这与Perl无关,所以我把标签去掉了。

标签: java regex lookahead


【解决方案1】:

这个

^/[^/]+/details/[^/]+$

将匹配

/Raj/details/002-542545-1145457

但不是

/Raj/details/002-542545-1145457/show

【讨论】:

  • 但它也匹配这个 /Raj/details/002-542545-1145457/show/details/dsdf
  • 你的也是。那你要^/[^/]+/details/[^/]+?$吗?
  • 感谢 garyh 和 @ikegami,它运行良好。但是为什么最后一部分是勉强量词(+?)而第一部分是贪婪量词(+)?
  • @Reddy,贪婪在这个表达中是无关紧要的。您可以在这两个地方同时使用++?。 (好吧,如果字符串较长,它可能会影响性能,但不会影响匹配的内容。)我并不是要在我的正则表达式中使用.+?;我从 garyh 复制并粘贴它而没有注意到。我已从答案中删除了非贪婪修饰符。
  • @Reddy,如果其中一个更快,我想那就是那个。
【解决方案2】:

我认为你的正则表达式没有做你期望它做的事情。您缺少在/details/ 之后捕获数字数据的表达式的一部分。

您的正则表达式对.find() 是肯定的,因为字符串中存在与您当前表达式的匹配项,但字符串与表达式不完全匹配,这就是.matches() 不起作用的原因。

您当前的表达式不是贪婪搜索,它一到达/details/ 就会停止匹配。如果在/details/ 之后有/,则匹配失败,因此它与/details/ 和任何潜在/ 之间的字符不匹配 - 在您的示例中,数字数据。这会导致 .matches() 失败,即使仍然存在正匹配。

如果您希望它匹配整个字符串直到并包括数字但之后不匹配,则以下正则表达式应该有效:/.*/details/[0-9\-]*(?!.*/) - .find().matches() 都将返回正数,因为表达式是现在将所有内容与潜在的/ 匹配。

【讨论】:

  • 是的,你错过了正则表达式的一部分。您的正则表达式在 details/ (数字)之后不匹配字符,它只是匹配数字之前没有后跟 / 的内容。这不是贪婪的搜索。如果你使用 my 或 @garyh 的表达式,你应该会得到预期的结果。
  • +1,感谢您解释 find() 和 matches() 之间的区别。对于问题的其他部分,garyh 的表情看起来好多了,因此接受了这个答案。
【解决方案3】:

你的正则表达式看起来不错。 matcher() 只匹配整个字符串,而find() 匹配字符串中的下一个子字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2021-03-05
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多