我有以下正则表达式,我想抓住从句子开头到第一个##
的所有内容。我可以使用strsplit
来演示执行此任务,但我更喜欢gsub
解决方案。如果gusub
不是正确的工具(我认为是),我更喜欢基础解决方案,因为我想学习基础正则表达式工具。
x <- "gfd gdr tsvfvetrv erv tevgergre ## vev fe ## vgrrgf"
strsplit(x, "##")[[c(1, 1)]] #works
gsub("(.*)(##.*)", "\\1", x) #I want to work
答案 0 :(得分:13)
只需添加一个字符,在第一个量词之后添加?
即可使其“非贪婪”:
gsub("(.*?)(##.*)", "\\1", x)
# [1] "gfd gdr tsvfvetrv erv tevgergre "
以下是?regex
默认情况下,重复是贪婪的,所以最大可能的数量 使用重复。可以通过追加将其更改为“minimal” '?'到量词。
答案 1 :(得分:4)
我会说:
sub("##.*", "", x)
删除第一次出现##
之后的所有内容。
答案 2 :(得分:4)
在这种情况下,我会反过来说,即用空字符串替换#
后的所有内容:
gsub("#.*$", "", x)
[1] "gfd gdr tsvfvetrv erv tevgergre "
但您也可以使用非贪婪修饰符?
以您建议的方式使用正则表达式:
gsub("(.*?)#.*$", "\\1", x)
[1] "gfd gdr tsvfvetrv erv tevgergre "
答案 3 :(得分:2)
这是另一种使用更多字符串工具而不是更复杂的正则表达式的方法。它首先找到第一个##的位置,然后将子字符串提取到该点:
library(stringr)
x <- "gfd gdr tsvfvetrv erv tevgergre ## vev fe ## vgrrgf"
loc <- str_locate(x, "##")
str_sub(x, 1, loc[, "start"] - 1)
一般来说,我认为这种逐步的方法比复杂的正则表达式更易于维护。
答案 4 :(得分:1)
尝试将此作为正则表达式
^[^#]+
从字符串的开头开始,匹配任何不是#
的内容,直到第一个#
答案 5 :(得分:1)
这里有几个更简单的答案,但是既然你在问题中表明你想要了解基础R中的正则表达式支持,这是另一种方式,使用正向前瞻断言(?=#)
和非贪婪选项(?U)
。
regmatches(x, regexpr('(?U)^.+(?=#)', x, perl=TRUE))
[1] "gfd gdr tsvfvetrv erv tevgergre "