提取一些异常的字符串

时间:2018-10-12 09:50:04

标签: r regex

我有一堆这种模式的字符串:

w <- c("milan 01", "New York", "las vegas 123", "London abc")

我只想提取城市名称,即第一个字符串或前两个字符串,中间用空格隔开。

但是对于"London"之类的情况,我也必须作例外处理。

(为简化此问题,我可以将字符串"abc"作为例外传递给正则表达式。)

我已经做到了:

library(stringr)

str_extract(w, "^\\S*\\s+(\\S+)")
#[1] "milan 01"   "New York"   "las vegas"  "London abc"

str_extract(w, "^\\S*\\s+(\\S+)(\\D)") # can't understand why this won't work
#[1] NA           "New York"   "las vegas " "London abc"

所需:

#[1] "milan"   "New York"   "las vegas"  "London"

1 个答案:

答案 0 :(得分:3)

您可以使用

> library(stringr)
> w <- c("Milan 01", "New York", "Las vegas 123", "London abc")
> str_extract(w, "^\\p{L}+(?:\\s+(?!abc\\b)\\p{L}+)?")
# => [1] "milan"     "New York"  "las vegas" "London"  

如果第一个单词也不能是abc,则将前瞻性添加到开头:

> str_extract(w, "^(?!abc\\b)\\p{L}+(?:\\s+(?!abc\\b)\\p{L}+)?")   
                   ^^^^^^^^^^

详细信息

  • ^-字符串的开头
  • \\p{L}+-1个以上的字母(如果您计划仅支持ASCII,则可以改用[a-zA-Z]+
  • (?:\\s+(?!abc\\b)\\p{L}+)?-的可选序列
    • \\s+-超过1个空格
    • (?!abc\\b)-当前位置右侧不允许整个单词abc
    • \\p{L}+-1个以上字母

等价于R sub的基数:

> sub("(?s)^(\\p{L}+(?:\\s+(?!abc\\b)\\p{L}+)?).*", "\\1", w, perl=TRUE)
> ## OR > sub("(?s)^(?!abc\\b)(\\p{L}+(?:\\s+(?!abc\\b)\\p{L}+)?).*", "\\1", w, perl=TRUE)
[1] "milan"     "New York"  "las vegas" "London"

在这里,(?s)使.匹配包括换行符在内的任何字符,整个特定部分都被包裹在捕获括号中,并且匹配项被替换为Group 1值。