用于子字符串捕获的正则表达式,但子字符串可能会或可能不会被转义的双引号绑定

时间:2016-10-21 15:49:50

标签: r regex

假设我有以下字符串:

  1. “LAWNº1234/ 1998 - DATE 01/01/1998 \”LAW TITLE HERE \“。”
  2. “LEINº1234/ 1998 - 日期01/01 / 1998LAW标题可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N”
  3. 说明:

    • 甲。我在子字符串中有一些唯一的标识符(“LAWNº    NNNN / YYYY“)后跟” - “
    • B中。然后是DATE标识符,前面是单词“DATE”
    • ℃。然后是标准的大陆格式日期(“DD / MM / YYYY”)
    • d。最后是包含文档标题
    • 的子字符串

    注意: 例外情况是标题子字符串 可能包含也可能不包含在双引号中

    注意: 所有标题都具有以下功能;可能会也可能不会开始(或包含)字母和数字字符以及标点符号(句号结尾处的完整句点或句号或其他标点符号中包含逗号,分号或冒号)。

    我的问题: 我如何能够最有效地修改下面构造的类Perl正则表达式,以处理未被捕获的标题子字符串的异常双引号?简而言之,我想从字符串中保留(或保留)title子字符串,无论它是否被上面列出的两种类型的字符串中的双引号捕获。

    当前,类似Perl的正则表达式:

      

    '(?< = DATE \ d {2} / \ d {2} / \ d {4}(\“| \ s +))(。*)$'

    示例代码&数据

    s1<- "LAW Nº 1234/1998 - DATE 01/01/1998\"LAW TITLE HERE MAY CONTAIN 4|_|D4NUM3R!C OR P_NC7U@7|()N\"."
    
    s2<-"LAW Nº 1234/1998 - DATE 01/01/1998LAW TITLE HERE MAY CONTAIN 4|_|D4NUM3R!C OR P_NC7U@7|()N"
    
    p<-'(?<=DATE \\d{2}/\\d{2}/\\d{4}(\"|\\S))(.*)$'
    
    m1<-regexpr(p, s1,perl=T)
    
    m2<-regexpr(p, s2,perl=T)
    
    t1<-regmatches(s1, m1)
    
    t2<-regmatches(s2, m2)
    
    print(t1)
    
    print(t2)
    

    返回:

    1.   

      “LAWNº1234/ 1998 - 日期01/01/1998”法律标题可能包含在这里   4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N \“。”

    2.   

      “AW TITLE HERE 5可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N”

    3. 当前的实施问题,需要修复:

      1. 字符串1有一个最后的'\“',它是一个转义的双引号 需要从最终产出中排除。
      2. 当前正则表达式构造首先排除 检测到非空白字符。
      3. 所需的输出(来自两个子字符串的相同输出):

          
            
        1. “法律标题可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N。”
        2.   
        3. “法律标题可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N。”
        4.   

        R会话信息(基础R,无附加包):

          

        R版本3.2.4(2016-03-10)平台:x86_64-apple-darwin13.4.0   (64位)运行于:OS X 10.11.5(El Capitan)

3 个答案:

答案 0 :(得分:0)

到目前为止,我能提出最有效的解决方案:

类似Perl的正则表达式:

  

&#39;(?&lt; = DATE [\ d /] {10})(\&#34; | \ w)[^ \&#34;] +&#39;

<强> 代码:

p<-'(?<=DATE [\\d/]{10})(\"|\\w)[^\"]+'

m1<-gregexpr(p,s1,perl=T)

t1<-gsub('\"', '', regmatches(s1, m1)[[1]])

m2<-gregexpr(p,s2,perl=T)

t2<-gsub('\"', '', regmatches(s2, m2)[[1]])

print(t1)

print(t2)

答案 1 :(得分:0)

此处使用PCRE的最佳方法是使用branch reset group(?|...|...)并在每个分支中使用捕获组,仅将结果输入到第1组。

但是,有助于在R中提取捕获的组值的regexec函数不接受perl=TRUE参数,也不能在 stringr str_match / str_match_all

此处使用分支重置最方便的方法是通过sub

> p <- "(?s).*DATE \\d{2}/\\d{2}/\\d{4}(?|\"(.*)\".*|(.*))|.+"
> x <- c("LAW Nº 1234/1998 - DATE 01/01/1998\"LAW TITLE HERE MAY CONTAIN 4|_|D4NUM3R!C OR P_NC7U@7|()N\".","LAW Nº 1234/1998 - DATE 01/01/1998LAW TITLE HERE MAY CONTAIN 4|_|D4NUM3R!C OR P_NC7U@7|()N", "Something that does not match")
> sub(p, "\\1", x, perl=TRUE)
[1] "LAW TITLE HERE MAY CONTAIN 4|_|D4NUM3R!C OR P_NC7U@7|()N"
[2] "LAW TITLE HERE MAY CONTAIN 4|_|D4NUM3R!C OR P_NC7U@7|()N"
[3] "" 

请参阅regex demoonline R demo

模式匹配字符串与我们的模式(即捕获到第1组)首先使用第一个外部分支,或者整个字符串如果没有我们感兴趣的模式将其完全删除为结果。

模式详情

  • (?s) - 启用.以匹配换行符号
    • .* - 尽可能多地匹配任何0+字符直到最后
    • DATE \d{2}/\d{2}/\d{4} - DATE后跟一个空格,2位数,/,2位数,/,4位
    • (?|"(.*)".*|(.*)) - 分支重置组匹配
      • "(.*)".* - ",尽可能多的0个字符(第1组),"
      • | - 或
      • (.*) - 第1组捕获任何0+字符
  • | - 或
    • .+ - 只匹配一个非空字符串,任意一个或多个字符。

答案 2 :(得分:0)

您可以在Results<FieldValue>中使用此正则表达式:

gsub

示例:

.+?DATE [0-9/]{10}|\"

这里,标题前的所有内容和所有双引号都被空字符串替换。