【问题标题】:How to delete parts of a textual vector using gsub and regular expressions如何使用 gsub 和正则表达式删除部分文本向量
【发布时间】:2019-06-28 18:36:17
【问题描述】:

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

如果与正则表达式一起使用,我相信 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&lt;-gsub("[^((?&lt;=^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|”。此外,Lookaround 之后的 ^ 似乎不能用作锚点,而只是用作附加标点符号。

期望的结果如下:

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

非常感谢任何帮助。

【问题讨论】:

  • 正则表达式仅适用于字符串,不适用于向量等其他数据类型。

标签: r regex replace gsub regex-lookarounds


【解决方案1】:

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

请注意,我们使用sub 而不是gsub,因为每个组件只有一个整体匹配。此外,它会在 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."

添加

【讨论】:

    【解决方案2】:
        gsub("^([^.]*.[^.]*).*", "\\1.", v)
    
    [1] "M. le président."               "M.Gabriel Xaaperei."           
    [3] "M. Raymond Fornir, rapporteur."
    

    【讨论】:

      【解决方案3】:

      您将正则表达式放在方括号中,R 将其解释为一个组,然后确实将该组中的所有内容视为“OR”。您还在前面加上 ^,这使得 R 将其视为“NOT”,因此它基本上会查找除搜索词中的字符之外的任何内容。 此外,你没有逃脱你的时期。这是应该的正则表达式:

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

      这会查找 M.(句点已转义),然后是任何(未转义的 .)未确定次数(*),然后是第二个(转义)句点(? 是以确保它是不贪婪的,所以它不会寻找最后一个时期,而只寻找下一个时期)。

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

      【讨论】:

      • 感谢您的逐步解释。我以前没有遇到过 (\\1) 。出于好奇:它是如何工作的?它在 gsub 函数的“模式”部分中指的是什么?如果我将其更改为(\\2),则所有内容都被丢弃并且没有输出。
      • \\1 指的是括号的内容。如果您有多个括号表达式,您可以使用 \\n 引用它们。 (例如,参见已接受答案中的第一个解决方案)
      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多