我们说我有以下字符串:
input = "askl jmsp wiqp;THIS IS A MATCH; dlkasl das, fm"
我需要用下划线替换白色空格,但只能在与模式匹配的子串中。 (在这种情况下,模式在前后都是分号。)
预期输出应为:
output = "askl jmsp wiqp;THIS_IS_A_MATCH; dlkasl das, fm"
任何想法如何实现,最好使用正则表达式,而不分割字符串?
我试过了:
gsub("(.*);(.*);(.*)", "\\2", input) # Pattern matching and
gsub(" ", "_", input) # Naive gsub
但是,不能把它们放在一起。
答案 0 :(得分:4)
关于原始问题:
在匹配的子字符串中替换字符
您可以使用gsubfn
轻松完成:
> library(gsubfn)
> input = "askl jmsp wiqp;THIS IS A MATCH; dlkasl das, fm"
> gsubfn(";([^;]+);", function(g1) paste0(";",gsub(" ", "-", g1, fixed=TRUE),";"), input)
[1] "askl jmsp wiqp;THIS-IS-A-MATCH; dlkasl das, fm"
;([^;]+);
匹配以;
开头的任何字符串,直到下一个;
捕获中间文本,然后仅在捕获的部分内用连字符替换空格。
另一种方法是使用基于\G
的正则表达式与gsub
的PCRE正则表达式:
p = "(?:\\G(?!\\A)|;)(?=[^;]*;)[^;\\s]*\\K\\s"
> gsub(p, "-", input, perl=TRUE)
[1] "askl jmsp wiqp;THIS-IS-A-MATCH; dlkasl das, fm"
模式详情:
(?:\\G(?!\\A)|;)
- 自定义边界:上一次成功匹配的结束(\\G(?!\\A)
)或(|
)分号(?=[^;]*;)
- 前瞻性检查:;
;
[^;\\s]*
- 除;
和空格\\K
- 省略目前为止匹配的文字\\s
- 1个单个空格字符(如果要用1个连字符替换多个空格,请在之后添加+
)。