正则表达式与负向前瞻匹配

时间:2013-11-06 14:10:21

标签: regex r negative-lookahead

我正在尝试编写一个正则表达式,其匹配模式排除某些字符串。它应该删除所有出现的仅数字和字母数字字符串,并删除所有标点符号,但保留一些有意义的字符串(911,K-12,K9,E-COMMERCE等)。

我认为我需要使用否定前瞻并指定需要跳过的内容。匹配模式几乎可以根据需要工作,但有一些模式不起作用。下面是代码,以及匹配的结果。有几个我已经指定了结果应该是什么。我无法弄清楚的是一个带有标点,数字和字符组合的字符串。任何帮助是极大的赞赏。感谢。

blah <- c('ASDF911 2346', 'E-COMMERCE', 'AMAZON E-COMMERCE', 'K-12 89752 911', '65426 -', 'TEACHERK-12', 'K9 OFFICER', 'WORK - K-9564', 'DEVELOPER C++', ' C+ C +5', 'DEFAULT - 456')
gsub('(^| )(?!(911|E[-]COMMERCE|K[-]12|C[+]{1,2}))([[:punct:]]|[0-9]+|([0-9]+[A-Z]+|[A-Z]+[0-9]+)[0-9A-Z]*)', ' ', blah, perl = TRUE)

" "                     # OK
"E-COMMERCE"            # OK
"AMAZON E-COMMERCE"     # OK
"K-12  911"             # OK
"  "                    # OK
"TEACHERK-12"           # this should be "  "
"K9 OFFICER"            # OK
"WORK K-9564"           # this should be "WORK   "
"DEVELOPER C++"         # OK
" C+ C 5"               # this should be " C+ C "
"DEFAULT  "             # OK

1 个答案:

答案 0 :(得分:1)

更容易匹配两者,然后替换为白名单的关键字:

gsub('(?:\\b(911\\b|E-COMMERCE\\b|K-12\\b|C\\b[+]{0,2})|[[:punct:]]|[A-Z-]*[0-9][A-Z0-9-]*)', '\\1', blah, perl = TRUE)

输出:

" "
"E-COMMERCE"
"AMAZON E-COMMERCE"
"K-12  911"
" "
""
" OFFICER"   # Should this really be "K9 OFFICER"?
"WORK  "
"DEVELOPER C++"
" C+ C "
"DEFAULT  "
  • \b是一个单词边界。它匹配一系列单词字符([A-Za-z0-9_])边缘的空字符串。它是(?<!\w)(?=\w)|(?<=\w)(?!\w)的优化版本。
  • [A-Z-]*[0-9][A-Z0-9-]*匹配字母,数字和短划线的字符串,其中至少包含一位数字。

http://ideone.com/E3TUU5