匹配重复字符的第一个实例的正则表达式

regular expression to match up to first instance of repeated character

我的示例数据:

l1
[1] "xmms-1.2.11-x86_64-5"     "xmms-1.2.11-x86_64-6"    
[3] "xmodmap-1.0.10-x86_64-1"  "xmodmap-1.0.9-x86_64-1"  
[5] "xmodmap3-1.0.10-x86_64-1" "xmodmap3-1.0.9-x86_64-1"

我正在使用 R 并且想要一个只捕获第一个破折号之前的字符的正则表达式。如

xmms
xmms
xmodmap
xmodmap
xmodmap3
xmodmap3

由于我使用的是 R,因此正则表达式需要符合 Perl。

我以为我可以通过在破折号上使用后视来做到这一点,但我只是得到了整个字符串的匹配项。这是我尝试过的模式: grepl("(?<=[a-z0-9])-",l1, perl=T) ,但它只匹配整个字符串。我认为如果我将第一个破折号作为捕获组,我也许可以使用后视,但我不知道如何使用后视和捕获组构建正则表达式。

我查看了其他一些问题以寻找可能的答案,看来我可能需要一个非贪婪符号?我试过 grepl("(?<=[a-z0-9])-/.+?(?=-)/",l1, perl=T),但也没用。

我愿意听取有关如何在破折号之前捕获第一组字符的其他建议。我目前在 base R,但我可以使用任何包,比如 stringr。

1) Base R 一个选项是 subbase R 匹配 - 后跟字符 (.* ) 然后替换为空白 ("")

sub("-.*", "", l1)
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

或集体捕获

sub("(\w+).*", "\1", l1)
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

regmatches/regexpr

regmatches(l1, regexpr('\w+', l1))
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

或使用trimws

trimws(l1,  "right", whitespace = "-.*")
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

或使用read.table

read.table(text = l1, sep="-", header = FALSE, stringsAsFactors = FALSE)$V1
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

strsplit

sapply(strsplit(l1, "-"), `[`, 1)

2) stringr 或使用 stringr

中的 word
library(stringr)
word(l1, 1, sep="-")

str_remove

str_remove(l1, "-.*")
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

3) stringi 或者 stri_extract_first 来自 stringi

library(stringi)
stri_extract_first(l1, regex = "\w+")
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

注意:grep/grepl用于检测字符串中的模式。对于 replacing/extracting 子串,在 base R

中使用 sub/regexpr/regmatches

数据

l1 <- c("xmms-1.2.11-x86_64-5", "xmms-1.2.11-x86_64-6", "xmodmap-1.0.10-x86_64-1", 
"xmodmap-1.0.9-x86_64-1", "xmodmap3-1.0.10-x86_64-1", "xmodmap3-1.0.9-x86_64-1"
)

您也可以提取直到第一次出现 "-"。使用基数 R sub

sub("(.*?)-.*", "\1", l)
#[1] "xmms"     "xmms"     "xmodmap"  "xmodmap"  "xmodmap3" "xmodmap3"

stringr::str_extract

stringr::str_extract(l, "(.*?)(?=-)")

数据

l <- c("xmms-1.2.11-x86_64-5","xmms-1.2.11-x86_64-6","xmodmap-1.0.10-x86_64-1",
  "xmodmap-1.0.9-x86_64-1","xmodmap3-1.0.10-x86_64-1" ,"xmodmap3-1.0.9-x86_64-1")

我想最简单的正则表达式可以满足您的需求

^[^-]+

匹配字符串开头 (^) 和至少一个不是 - ([^-]) 的字符 (+)。

See it here at regex101.

如果您需要捕获它,请添加括号。

^([^-]+)