阿肖克已经指出的区别.*
和.*?
,所以我就提供一些额外的信息。
grep
(假设是GNU版本)支持4种匹配字符串的方法:
- 固定弦
- 基本正则表达式(BRE)
- 扩展正则表达式(ERE)
- Perl兼容的正则表达式(PCRE)
grep
默认情况下使用BRE。
BRE和ERE记录在POSIX 的“ 正则表达式”一章中,PCRE记录在其官方网站上。请注意,功能和语法可能因实现而异。
值得一提的是,BRE和ERE都不支持惰性:
多个相邻重复符号(“ +”,“ *”,“?”和间隔)的行为会产生不确定的结果。
因此,如果要使用该功能,则需要使用PCRE:
# BRE greedy
$ grep -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants
# BRE lazy
$ grep -o 'c.*\?s' <<< 'can cats eat plants?'
can cats eat plants
# ERE greedy
$ grep -E -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants
# ERE lazy
$ grep -E -o 'c.*?s' <<< 'can cats eat plants?'
can cats eat plants
# PCRE greedy
$ grep -P -o 'c.*s' <<< 'can cats eat plants?'
can cats eat plants
# PCRE lazy
$ grep -P -o 'c.*?s' <<< 'can cats eat plants?'
can cats
编辑1
你能解释一下.*
vs .*?
吗?
.*
用于匹配可能的“最长” 1模式。
.*?
用于匹配“最短” 1模式。
以我的经验,最想要的行为通常是第二个。
例如,假设我们有以下字符串,而我们只想匹配html标签2,而不是它们之间的内容:
<title>My webpage title</title>
现在比较.*
vs .*?
:
# Greedy
$ grep -P -o '<.*>' <<< '<title>My webpage title</title>'
<title>My webpage title</title>
# Lazy
$ grep -P -o '<.*?>' <<< '<title>My webpage title</title>'
<title>
</title>
正如Kusalananda指出的那样
,在正则表达式中“最长”和“最短”的含义有些棘手。有关更多信息,请参考官方文档。
2. 不建议使用regex解析html。这只是出于教育目的的示例,请勿在生产中使用。