使用正则表达式的非贪婪(惰性)匹配?

Non-greedy (lazy) matching using regex?

Stata 中如何使用正则表达式实现非贪婪匹配?或者 Stata 甚至有这种能力吗?

我想提取井号标签“#”和句点“.”之间出现的所有文本。

示例代码:

clear
set obs 3
generate var1="anything#aaabbbccc.dddeee.fff" in 1
replace var1="anything#aaabbbccc.dddeee" in 2
replace var1="anything#aaabbbccc." in 3
generate var2=regexs(1) if regexm(var1,"#(.*)\.")
list

但是在Stata (v.13.1) 中,我似乎无法使用非贪婪字符#(.*?)\.。因此,上面的代码给出了这个:

+--------------------------------------------------+
|                          var1               var2 |
|--------------------------------------------------|
| anything#aaabbbccc.dddeee.fff   aaabbbccc.dddeee |
|     anything#aaabbbccc.dddeee          aaabbbccc |
|           anything#aaabbbccc.          aaabbbccc |
+--------------------------------------------------+

但我想要的是:

+--------------------------------------------------+
|                          var1               var2 |
|--------------------------------------------------|
| anything#aaabbbccc.dddeee.fff          aaabbbccc |
|     anything#aaabbbccc.dddeee          aaabbbccc |
|           anything#aaabbbccc.          aaabbbccc |
+--------------------------------------------------+

使用 #(.*?)\. 的一种做法是只匹配井号后出现的任何非点字符,即此模式:

#([^.]*)

试试这个代码:

clear
set obs 3
generate var1="anything#aaabbbccc.dddeee.fff" in 1
replace var1="anything#aaabbbccc.dddeee" in 2
replace var1="anything#aaabbbccc." in 3
generate var2=regexs(1) if regexm(var1,"#([^.]*)")
list

Demo

一旦许多程序员了解了正则表达式,他们就不愿意在字符串管理方面寻找其他地方,这是有充分理由的。

这只是为了指出对于给定的问题以及许多其他问题,有一个行人的替代方案:

clear
set obs 3
generate var1="anything#aaabbbccc.dddeee.fff" in 1
replace var1="anything#aaabbbccc.dddeee" in 2
replace var1="anything#aaabbbccc." in 3
generate var2=regexs(1) if regexm(var1,"#([^.]*)")

gen where1 = strpos(var1, "#") + 1 
gen where2 = strpos(var1, ".") 
gen var3 = substr(var1, where1, where2 - where1)  

list


     +-------------------------------------------------------------------------+
     |                          var1        var2   where1   where2        var3 |
     |-------------------------------------------------------------------------|
  1. | anything#aaabbbccc.dddeee.fff   aaabbbccc       10       19   aaabbbccc |
  2. |     anything#aaabbbccc.dddeee   aaabbbccc       10       19   aaabbbccc |
  3. |           anything#aaabbbccc.   aaabbbccc       10       19   aaabbbccc |
     +-----------------------------------------------------------------------

找到你想要的子字符串的开始和结束位置,并提取介于两者之间的内容。这绝对缺乏风格,但有时会让你更快。永远记住在计算你需要的正则表达式时要考虑程序员的时间。