假设arg如下:
tLUKErnttt(over comlink)rnttGood luck, LandornrnttttLANDOrnttt(into comlink)rnttWhen we find Jabba the Hut and rnttthat bounty hunter, we'll contact rnttyou.rnrn
我试图使用下面的代码来提取arg中以"t|n| & "+几个大写字母并以"rnrn"结尾,但我没有得到匹配:
str_extract_all(arg, "(t|n|r)[A-Z]{1}.*?[A-Z]{2}(rnttt).*?(?=(rnrn))")
我希望这段代码的结果是"tLUKErntt (over comlink)rntt祝你好运,Landornrn"rnttt(进入链接)rntt当我们找到小屋贾巴和那个赏金猎人时,我们会联系rntt你的。rnrn n"
当我在末尾取消正向查找时,匹配正常,并且返回"tLUKErnttt"one_answers" tLANDO r n t t"如预期。
str_extract_all(arg, "(t|n|r)[A-Z]{1}.*?[A-Z]{2}(rnttt).*?")
我在这里错过了什么?
默认情况下,点(.
)不匹配换行符(例如,参见help(stri_opts_regex)
中的dotall
选项),这就是为什么.*?
部分不能捕获您想要的内容。您可以通过(?s)
标志启用此功能:
str_extract_all(arg, "(?s)(t|n|r)[A-Z]{1,}(rnttt).*?(?=rnrn)")
[[1]]
[1] "tLUKErnttt(over comlink)rnttGood luck, Lando"
[2] "tLANDOrnttt(into comlink)rnttWhen we find Jabba the Hut and rnttthat bounty hunter, we'll contact rnttyou."
如果以后不需要该值,可以省略省略捕获组。此外,{1}
是多余的,可以删除。
使用模式行.*?
只在结尾将不会产生任何匹配,因为量词是非贪婪的,并且没有规则让它放弃任何匹配。
为了使模式不那么严格,您可以使用量词来代替指定制表符和换行符的确切数量。
为了防止不必要的回溯,您可以匹配只包含大写字符的行,然后匹配所有不包含大写字符的行。
^[^Srn]+[A-Z]+(?:r?n(?![^Srn]*[A-Z]+$).*)*
^
字符串 起始[^Srn]+
匹配1+次不带换行符的空白字符[A-Z]+
匹配1+大写字符(?:
非捕获组r?n(?![^Srn]*[A-Z]+$
) '匹配换行符并断言该行不包含单个大写单词.*
如果前面的断言为真,匹配整行
)*
关闭组并重复0+次以匹配所有行
Regex演示
使用(?m)
多行
library(stringr)
arg <- "tLUKErnttt(over comlink)rnttGood luck, LandornrnttttLANDOrnttt(into comlink)rnttWhen we find Jabba the Hut and rnttthat bounty hunter, we'll contact rnttyou.rnrn"
str_extract_all(arg, "(?m)^[^\S\r\n]+[A-Z]+(?:\r?\n(?![^\S\r\n]*[A-Z]+$).*)*")
输出[[1]]
[1] "tLUKErnttt(over comlink)rnttGood luck, Landorn"
[2] "ttttLANDOrnttt(into comlink)rnttWhen we find Jabba the Hut and rnttthat bounty hunter, we'll contact rnttyou.rnrn"