R中正则表达式中的(^ | \\ s)([A-Z] {1,3})(\\ s | $)和\\ b [A-Z] {1,2} \\ b之间的差异

时间:2016-08-26 07:20:07

标签: regex r

我正在尝试清理存储在R Data Frame列中的一些小字符串(1-3个字母)。具体来说,假设下一个R脚本:

df = data.frame( "original" = c("ABCDE FG H",
                            "IJKL MN OPQRS", 
                            "TUV WX YZ AAAA"))
df$filter1 = gsub("(^|\\s)[A-Z]{1,2}($|\\s)", " ", df$original)
df$filter2 = gsub("\\b[A-Z]{1,2}\\b", " ", df$original)

> df

        original |    filter1 |    filter2  |
1     ABCDE FG H |    ABCDE H |    ABCDE    |
2  IJKL MN OPQRS | IJKL OPQRS | IJKL   OPQRS|
3 TUV WX YZ AAAA | TUV YZ AAAA|  TUV   AAAA |

我不明白为什么第一个过滤器(^|\\s)[A-Z]{1,2}($|\\s)不能替代" H"在第一行或" YZ"在第三个。我希望使用\\b[A-Z]{1,2}\\b作为过滤器(filter2列)的结果相同。请不要担心多个空格,这对我来说并不重要(除非这是问题所在:)。)

我认为问题在于"全球性"操作,它是否,如果它发现第一个没有替换第二个,但如果我做下一个替换它不是真的:

> gsub("A", "X", "AAAABBBBCCCDDDDAAAAAAAEEE")
[1] "XXXXBBBBCCCDDDDXXXXXXXEEE"

那么,为什么结果不同?

1 个答案:

答案 0 :(得分:3)

关键是Handler BobId只能匹配非重叠的字符串。 gsub是第一个预期匹配, FG 是第二个,您可以看到这些字符串重叠,因此, H消耗"(^|\\s)[A-Z]{1,2}($|\\s)"之后的尾随空格{1}},FG与模式不匹配。

看:从左到右分析H。表达式与ABCDE FG H匹配,正则表达式索引在 FG 之前。只有这封信匹配,但H需要一个空格或字符串的开头 - 此位置没有。

To" fix"这个和使用相同的逻辑,您可以使用PCRE正则表达式(^|\s) lookarunds

gsub

df$filter1 = gsub("(^|\\s)[A-Z]{1,2}(?=$|\\s)", " ", df$original, perl=TRUE)

如果您需要实际使用(删除)空格,只需在(或/和之后)之前添加df$filter1 = gsub("(?<!\\S)[A-Z]{1,2}(?!\\S)", " ", df$original, perl=TRUE)

第二个表达式\\s*包含单词边界,它们是不使用文本的零宽度断言,因此,正则空间引擎可以匹配"\\b[A-Z]{1,2}\\b"FG,因为空格不被消耗。