【问题标题】:Capture from 1st occurance of x to nth occurance of y从第一次出现 x 到第 n 次出现 y 捕获
【发布时间】:2021-08-27 18:23:50
【问题描述】:

我有一个看起来相当可行的正则表达式问题,但我似乎无法正确解决。

给出如下所示的字符串:

id1234|a; b; c; d
id5678|a; b; e; f
id9012|a; g; h; i

我正在尝试从管道中捕获固定出现的分号,直觉上我希望是这样的:

"(?<=\\|)(([^;]*;){1}[^;]*).*"

从管道中选择直到第二个分号,因为:

"^(([^;]*;){1}[^;]*).*"

选择从行首到第二个分号。

https://regexr.com/

相信:

(?<=\|)(([^;]*;){1}[^;]*).*

从管道开始正确选择,但似乎无法在正确的分号处结束捕获。

但在 R gsub 中抱怨:

a <- c("id1234|a; b; c; d",
       "id5678|a; b; e; f",
       "id9012|a; g; h; i",
       "id3456|a; j; k; l")

b <- gsub(pattern = "^(([^;]*;){1}[^;]*).*",
          replacement = "\\1",
          x = a)
b
[1] "id1234|a; b" "id5678|a; b" "id9012|a; g" "id3456|a; j"

c <- gsub(pattern = "(?<=\\|)(([^;]*;){1}[^;]*).*",
          replacement = "\\1",
          x = a)
Error in gsub(pattern = "(?<=\\|)(([^;]*;){1}[^;]*).*", replacement = "\\1",  : 
  invalid regular expression '(?<=\|)(([^;]*;){1}[^;]*).*', reason 'Invalid regexp'
In addition: Warning message:
In gsub(pattern = "(?<=\\|)(([^;]*;){1}[^;]*).*", replacement = "\\1",  :
  TRE pattern compilation error 'Invalid regexp'

【问题讨论】:

    标签: r regex gsub


    【解决方案1】:

    您收到错误是因为您使用了后视,(?&lt;=\|),但没有使用 perl=TRUE 参数来启用支持后视的 PCRE 正则表达式引擎。默认的 TRE 正则表达式引擎不支持环视。

    你需要匹配整个字符串:

    sub("^[^|]*\\|([^;]*;[^;]*).*", "\\1", a)
    

    查看regex demoR demo

    a <- c("id1234|a; b; c; d",
           "id5678|a; b; e; f",
           "id9012|a; g; h; i",
           "id3456|a; j; k; l")
    sub("^[^|]*\\|([^;]*;[^;]*).*", "\\1", a)
    ## => [1] "a; b" "a; b" "a; g" "a; j"
    

    正则表达式详细信息

    • ^ - 字符串开始
    • [^|]* - 除了| 之外的零个或多个字符
    • \| - 一个 | 字符
    • ([^;]*;[^;]*) - 第 1 组:除 ;; 之外的任何零个或多个字符,以及除 ; 之外的任何零个或多个字符
    • .* - 字符串的其余部分。

    如果你想extract,你应该实际使用extracting正则表达式方法,例如:

    a <- c("id1234|a; b; c; d", "id5678|a; b; e; f", "id9012|a; g; h; i", "id3456|a; j; k; l")
    unlist(regmatches(a, gregexpr("(?<=\\|)[^;]*;[^;]*", a, perl=TRUE)))
    ## => [1] "a; b" "a; b" "a; g" "a; j"
    
    library(stringr)
    str_extract(a, "(?<=\\|)[^;]*;[^;]*")
    ## => [1] "a; b" "a; b" "a; g" "a; j"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-07
      • 2018-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多