在Java中,正则表达式可以使用两种不同的量词模式来匹配字符序列:贪婪模式(greedy)和非贪婪模式(reluctant或lazy)。
贪婪模式 (Greedy)
默认情况下,正则表达式的量词是贪婪的。这意味着当一个量词可以匹配多个字符时,它会尽可能多地匹配。例如:
*
匹配前面的元素零次或多次。+
匹配前面的元素一次或多次。?
匹配前面的元素零次或一次。{n,m}
匹配前面的元素至少n次,至多m次。
这些量词在没有其他限制的情况下,总是尝试匹配尽可能长的字符串。
示例
假设我们有一个字符串 "abcabcabc"
和正则表达式 a.*c
,这里的 .*
是贪婪的,它会匹配从第一个 a
到最后一个 c
之间的所有字符,即整个字符串 "abcabcabc"
。
非贪婪模式 (Reluctant or Lazy)
非贪婪模式则是与贪婪模式相反的行为。当使用非贪婪量词时,它们会尽可能少地匹配字符。为了使量词变为非贪婪模式,可以在量词后面加上一个问号 ?
。
*?
匹配前面的元素零次或多次,但尽可能少。+?
匹配前面的元素一次或多次,但尽可能少。??
匹配前面的元素零次或一次,但尽可能少。{n,m}?
匹配前面的元素至少n次,至多m次,但尽可能少。
示例
如果使用相同的字符串 "abcabcabc"
但是正则表达式改为 a.*?c
,这里的 .*?
是非贪婪的,它会匹配从第一个 a
开始到最近的一个 c
之间的所有字符,即第一次匹配结果为 "abc"
,然后继续匹配下一段,直到所有的 "abc" 组合都被找到。
使用场景
- 贪婪模式 常用于需要获取最长可能匹配的情况。
- 非贪婪模式 常用于需要获取最短可能匹配的情况,特别是在处理HTML标签或其他需要精确控制匹配长度的文本时非常有用。
在编写正则表达式时,选择正确的模式对于确保你的程序能够正确解析目标文本是非常重要的。