我想根据某些标记有条件地替换文本中的字符。例如,在以下字符串中。
text <- "In Spanish, Brasil is written as <Brazil>, for some reason."
我想转换尖括号外的文本。我目前知道如何做相反的事情。我可以使用gsub((来识别指定字符串,并使用以下命令更改一些字符:
gsub("(<.*)z(.*?>)", "\1s\2", text)
[1] "In Spanish, Brasil is written as <Brasil>, for some reason."
但我想做的是在不影响尖括号内的文本,例如:
gsub("Brasil", "Brazil", text)
[1] "In Spanish, Brazil is written as <Brazil>, for some reason."
预期结果,仅更改尖括号外的文本:
[1] "In Spanish, Brazil is written as <Brazil>, for some reason."
我如何有条件地应用替换,使文本在角度内括号不受影响?我是否需要首先根据尖括号的存在来拆分字符串,应用替换项,然后合并所有字符串?或者我可以让它与gsub((和一个条件一起工作吗?
使用环视也有效:
sub("(?<!<)Brasil(?!>)", "Brazil", text, perl = TRUE)
工作原理:
(?<!<)
-反向查找,断言左边的下一个字符必须而不是为文字<
Brasil
-文字字符串Brasil
(?!>)
-否定前瞻,断言右边的下一个字符必须而不是为文字>
请注意,如果每个字符串只有一个替换项,那么sub
就足够了。如果要进行多个替换,则使用gsub
。
您需要在此处使用PCRE正则表达式(注意perl=TRUE
参数(:
gsub("<[^<>]*>(*SKIP)(*F)|Brasil", "Brazil", text, perl=TRUE)
详细信息:
<[^<>]*>(*SKIP)(*F)
-<
,除<
和>
之外的零个或多个字符,然后是>
,并且在该位置匹配失败,正则表达式引擎开始从失败位置搜索下一个匹配|
-或Brasil
-一个固定的字符序列
请参阅regex演示。
如果你只想";跳过";匹配 请参阅此regex演示。这里, 请参阅R演示(注意,我在尖括号内用Brasil
如果紧接着前面是<
,紧跟着gsub("(?<!<(?=\w+>))Brasil", "Brazil", text, perl=TRUE)
(?<!<(?=w+>))
是一个负查找,如果它前面紧跟着<
字符,后面紧跟着一个或多个单词字符和>
字符(即,如果Brasil
是,前面都是,后面都是<
和>
字符(,则匹配失败。Brasil
替换了Brazil
,以提高可见性(:text <- "In Spanish, Brasil is written as <Brasil>, for some reason."
gsub("<[^<>]*>(*SKIP)(*F)|Brasil", "Brazil", text, perl=TRUE)
# => [1] "In Spanish, Brazil is written as <Brasil>, for some reason."
text <- "In Spanish, Brasil is written as <Brasil>, for some reason."
gsub("(?<!<(?=\w+>))Brasil", "Brazil", text, perl=TRUE)
# => [1] "In Spanish, Brazil is written as <Brasil>, for some reason."