【发布时间】:2013-10-10 23:54:03
【问题描述】:
对于匹配字符串"fall/2005" 的".*?([a-m/]*).*",我认为".*" 将匹配任何字符0 次或更多次。但是,由于在.* 之后有一个?,它只匹配0 或1 次重复。所以我认为.*? 会匹配'f' 但我错了。
我的逻辑有什么问题?
【问题讨论】:
对于匹配字符串"fall/2005" 的".*?([a-m/]*).*",我认为".*" 将匹配任何字符0 次或更多次。但是,由于在.* 之后有一个?,它只匹配0 或1 次重复。所以我认为.*? 会匹配'f' 但我错了。
我的逻辑有什么问题?
【问题讨论】:
在正则表达式中:
? :不发生或发生一次,?是 {0,1}
的缩写
*? : ?在一个量词使它成为一个不情愿的量词之后,它会尝试找到最小的匹配。
【讨论】:
这里的? 充当“修饰符”,如果我可以这样称呼它并使.* 匹配尽可能少的匹配(称为“惰性”),直到模式中的下一个匹配。
在fall/2005 中,第一个.*? 将匹配([a-m/]*) 中的第一个匹配项,就在f 之前。因此,.*? 匹配 0 个字符,因此 ([a-m/]*) 将匹配 fall/,并且由于 ([a-m/]*) 无法再匹配,模式的下一部分 .* 匹配字符串中剩余的内容,即 2005。
与.*([a-m/]*).* 相比,您应该先让.* 尽可能多地匹配(表示整个字符串),然后尝试返回以使其他术语匹配。除了问题在于其他量词也能够匹配 0 个字符,因此单独的 .* 将匹配整个字符串(称为“贪婪”)。
也许一个不同的例子会有所帮助。
.*ab
在:
aaababaaabab
在这里,.* 将匹配尽可能多的字符,然后尝试匹配 ab。因此,.* 将匹配 aaababaaab,其余部分将匹配 ab。
.*?ab
在:
aaababaaabab
在这里,.*? 将尽可能少地匹配,直到它可以匹配该正则表达式中的 ab。 ab 第一次出现在这里:
aaababaaabab
^^
因此,.*? 匹配 aa 而ab 将匹配 ab。
【讨论】:
.*? 总是只匹配空字符串。介意举一个反例来证明.*? 何时真正匹配某些东西,甚至可能有用(即z01234z56789z,试图仅获取前两个zs 之间的内容)?
.*? 将匹配第一个 aa,除非您使用了 g 修饰符。
假设你有这样的字符串输入
this is stackoverflow
你使用正则表达式
.*
所以输出将是
this is stackoverflow
但是如果你使用正则表达式
.*?
你的输出将是
this
所以从上面的例子很明显,如果你使用 .* 它会给你整个字符串。 为防止这种情况发生,如果您只想要空格前的第一个 cherector,您应该使用 .*?
更多实用知识可以查看http://regexpal.com/
【讨论】:
.*?本身会选择匹配0字符。
?(问号)在这里被认为是懒惰或所谓的不贪婪。
你的正则表达式:
.*? any character except newline \n (0 or more times)
(matching the least amount possible)
( group and capture to \1:
[a-m/]* any character of: 'a' to 'm', '/' (0 or more times)
(matching the most amount possible)
) end of \1
.* any character except newline \n (0 or more times)
(matching the most amount possible)
【讨论】: