如何使用gsub和正则表达式删除文本向量的部分

时间:2019-06-28 18:36:17

标签: r regex replace gsub regex-lookarounds

我有一个列表,其中每个元素都包含一个文本数据向量。 本质上,我希望代码删除正则表达式后的文本:第二个“。”。在各自的向量中。

如果与正则表达式结合使用,我相信gsub函数是解决此问题的好方法。我试图使用正则表达式来制定要检测的模式(见下文)。

数据:

v<-c("M. le président. La parole est à M. Emile Vernaudon.",
       "M.Gabriel Xaaperei. Monsieur le ministre",
       "M. Raymond Fornir, rapporteur. La commission") 

代码:

Subbed<-gsub("[^((?<=^M. *))]", "X", v)

代码返回以下内容:

[1] "M. XX XXXXXXXXX. XX XXXXXX XXX. M. XXXXX XXXXXXXXX."
[2] "M. XXXXXXX XXXXXXXXX. MXXXXXXX XX XXXXXXXXX XXX"    
[3] "M. XXXXXXX XXXXXX XXXXXXXXXX. XX XXXXXXXXXX" 

该代码不仅考虑了所有的“ M”,而且第二行中还有一个“ M”,尽管其后没有一个“。”。 我的直觉是,在gsub中,正则表达式的工作方式似乎有所不同-“ M”。在我的代码中,R可能会将其读取为“ M |”。另外,“环顾四周”后面的^似乎不能用作锚点,而只能用作其他标点符号。

期望的结果如下:

[1] "M. le président."
[2] "M. Gabriel Xaaperei."
[3] "M. Raymond Fornir, rapporteur."

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

1)sub 匹配字符串(^)的开头,然后捕获M。下一步匹配空格(如果有),然后捕获所有内容,直到下一个点。最后匹配其他所有内容。将其替换为第一个捕获(\ 1),一个空格和第二个捕获(\ 2)。

请注意,由于每个组件只有一个整体匹配项,因此我们使用sub而不是gsub。另外,即使M之前没有空格,它也会在M后面放置一个空格。

sub("^(M\\.) *([^.]+\\.).*", "\\1 \\2", v)

给予:

[1] "M. le président."               "M. Gabriel Xaaperei."          
[3] "M. Raymond Fornir, rapporteur."

2)read.table 此解决方案不使用任何正则表达式。我们使用点分隔的字段读取v,然后使用sprintf将它们重新组合在一起。

with(read.table(text = v, sep = ".", fill = TRUE, strip.white = TRUE), 
  sprintf("%s. %s.", V1, V2))

给予:

[1] "M. le président."               "M. Gabriel Xaaperei."          
[3] "M. Raymond Fornir, rapporteur."

3)paste / trimws / sub (粘贴/整理/订阅),该函数使用多个函数和一个正则表达式,这相对简单。我们从第3个字符开始取所有内容,将第一个点及其后的所有内容替换为一个点,修剪空白以防万一,然后将M.粘贴到开头。

paste("M.", trimws(sub("\\..*", ".", substring(v, 3))))

给予:

[1] "M. le président."               "M. Gabriel Xaaperei."          
[3] "M. Raymond Fornir, rapporteur."

添加

答案 1 :(得分:2)

    gsub("^([^.]*.[^.]*).*", "\\1.", v)

[1] "M. le président."               "M.Gabriel Xaaperei."           
[3] "M. Raymond Fornir, rapporteur."

答案 2 :(得分:1)

您将正则表达式放在方括号中,R将其解释为一个组,然后实际上将该组中的所有内容都视为“ OR”。您还以^开头,这使R将其视为“ NOT”,因此它基本上只查找搜索词中的字符。 此外,您没有逃脱自己的时期。这是应有的正则表达式:

gsub("^(M\\..*?\\.).*","\\1",v)
[1] "M. le président."               "M.Gabriel Xaaperei."           
[3] "M. Raymond Fornir, rapporteur."

这将查找M.(转义的时间),然后是未确定次数(*)之后的任何内容(未转义的。),然后是第二个(转义的)时间段( ?的目的是确保它不会感到贪婪,因此它不会寻找最后一个时期,而只会寻找下一个时期。

它们将所有内容返回到那里(\\1),并丢弃其余的内容。