【问题标题】:Non-greed regex misunderstanding, /\/.*?$/ act like greed [duplicate]非贪婪的正则表达式误解,/\/.*?$/ 表现得像贪婪[重复]
【发布时间】:2019-04-20 15:08:24
【问题描述】:

我正在用 javascript 试试这个

/\/.*?$/.exec('foo/bar/tar')[0]

我期待得到/tar,但得到/bar/tar。据我了解,非贪婪正则表达式将采用最小的匹配。

我用myvar.split('/').reverse()[0] 绕过了这个,但我不明白正则表达式出了什么问题。

【问题讨论】:

  • 您的模式\/.*?$ 匹配从第一个正斜杠到字符串末尾,即/bar/tar 如果您想要匹配,您可以匹配正斜杠而不是斜杠\/[^\/]+$ demo
  • 所以\/.*?$ 等于\/.*$ 我知道非贪婪的正则表达式有效,但我只是错过了这个概念。我认为这是匹配较小的可能匹配,这将是 /tar 而不是 /bar/tar 那么非贪婪的正则表达式有什么意义?!
  • 您错过了正则表达式从左到右与输入字符串的每个位置匹配的点。 /.*?$/.*$ 之间的区别在于惰性版本一次匹配一个字节,然后检查下一个位置是否是输入字符串的结尾,如果不是,则按字节扩展匹配,然后再次检查输入字符串的结尾。 . 但是对于贪心版本,. 匹配的所有内容都会立即从第一个 / 开始消耗,然后检查下一个直接位置是否是输入字符串的结尾。所以他们并不完全平等。从两个 RE 中删除 $ 以查看它们的行为。
  • revo 您可以发布答案吗?我刚收到
  • .*? 不匹配最短但匹配第一个可能出现的位置。这是更好的定义。

标签: javascript regex regex-greedy


【解决方案1】:

正则表达式没有任何问题,但模式 \/.*?$ 匹配从第一个正斜杠到字符串结尾非贪婪。

点匹配除换行符以外的任何字符并且不考虑正斜杠,因此将产生/bar/tar

如果你想匹配/tar,你可以匹配一个正斜杠,然后使用negated character class不再匹配正斜杠,然后断言字符串的结尾。

\/[^\/]+$

Pattern demo

console.log(/\/[^\/]+$/.exec('foo/bar/tar')[0]);

【讨论】:

  • 我知道我可以使用否定字符,但这不是问题。 myvar.split('/').reverse()[0] 也是可能的,而且可读性也更强,问题​​是我认为我知道非贪婪的概念,但似乎我不知道。
  • 贪婪的.* 尽可能匹配除换行符以外的任何字符。非贪婪的.*? 尽可能少地匹配并放弃尽可能少的匹配以适应整个模式。在这种情况下,后面跟着$ 断言行尾,因此.*.*? 将匹配相同,只是匹配的方式不同。比如看到这个这个greedy match,这个非greedy example
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2011-04-27
  • 2010-10-20
  • 1970-01-01
相关资源
最近更新 更多