【问题标题】:Regex matching everything that's not a 4 digit number正则表达式匹配所有不是 4 位数的数字
【发布时间】:2012-08-24 19:34:12
【问题描述】:

我匹配并替换前面和后面的空格的 4 位数字:

str12 <- "coihr 1234 &/()= jngm 34 ljd"
sub("\\s\\d{4}\\s", "", str12)
[1] "coihr&/()= jngm 34 ljd"

但是,每次尝试反转它并提取数字都会失败。 我要:

[1] 1234

有人知道吗?

ps:我知道如何用 {stringr} 做到这一点,但我想知道它是否可能只用 {base}..

require(stringr)
gsub("\\s", "", str_extract(str12, "\\s\\d{4}\\s"))
[1] "1234"

【问题讨论】:

    标签: regex r


    【解决方案1】:

    regmatches(),仅从 R-2.14.0 开始可用,允许您“从 regexprgregexprregexec 获得的匹配数据中提取或替换匹配的子字符串”

    以下是如何使用regmatches() 提取输入字符串中的第一个空格缓冲的4位子字符串或所有子字符串的示例.

    ## Example strings and pattern
    x <- "coihr 1234 &/()= jngm 34 ljd"          # string with 1 matching substring
    xx <- "coihr 1234 &/()= jngm 3444  6789 ljd" # string with >1 matching substring
    pat <- "(?<=\\s)(\\d{4})(?=\\s)"
    
    ## Use regexpr() to extract *1st* matching substring
    as.numeric(regmatches(x, regexpr(pat, x, perl=TRUE)))
    # [1] 1234
    as.numeric(regmatches(xx, regexpr(pat, xx, perl=TRUE)))
    # [1] 1234
    
    
    ## Use gregexpr() to extract *all* matching substrings
    as.numeric(regmatches(xx, gregexpr(pat, xx, perl=TRUE))[[1]])
    # [1] 1234 3444 6789
    

    (请注意,对于不包含与您的条件匹配的子字符串的字符串,这将返回 numeric(0))。

    【讨论】:

    • @JoshObrien : +1 很好地使用了regmatches
    • 我已经接受了 dickoa 的回答。不过,非常感谢您发布此方法 +1!
    • 这里的另一个选项是使用\b\\d{4}\b - 如果数字在字符串的开头,它也可以工作。 (但是,它也会匹配其他情况,例如"abc(1234)")。当然,OP确实说“前后有空格”,所以它可能没用:P
    • 谢谢@Kobi! ..根本没用:事实上,我很想知道如果数字位于一行的开头/结尾,我该如何处理..
    • @Kobi:我必须在哪里放置反向引用的括号?我无法使用它:gsub(".*(\b\\d{4}\b).*", "\\1", str12)..
    【解决方案2】:

    可以使用() 在正则表达式中捕获组。举个例子

    str12 <- "coihr 1234 &/()= jngm 34 ljd"
    gsub(".*\\s(\\d{4})\\s.*", "\\1", str12)
    [1] "1234"
    

    【讨论】:

    • 是的。我们一定是同时输入了相同的行...我刚刚删除了第一次尝试,并发布了第二个更好的解决方案,确实提取了第一个匹配项。
    【解决方案3】:

    总的来说,我对正则表达式非常幼稚,但这是在 base 中实现它的一种丑陋的方式:

    # if it's always in the same spot as in your example
    unlist(strsplit(str12, split = " "))[2]
    
    # or if it can occur in various places
    str13 <- unlist(strsplit(str12, split = " "))
    str13[!is.na(as.integer(str13)) & nchar(str13) == 4] # issues warning
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多