假设我有以下字符串:
说明:
注意: 例外情况是标题子字符串 可能包含也可能不包含在双引号中
注意: 所有标题都具有以下功能;可能会也可能不会开始(或包含)字母和数字字符以及标点符号(句号结尾处的完整句点或句号或其他标点符号中包含逗号,分号或冒号)。
我的问题: 我如何能够最有效地修改下面构造的类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)
返回:
“LAWNº1234/ 1998 - 日期01/01/1998”法律标题可能包含在这里 4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N \“。”
“AW TITLE HERE 5可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N”
当前的实施问题,需要修复:
所需的输出(来自两个子字符串的相同输出):
- “法律标题可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N。”
- “法律标题可能包含4 | _ | D4NUM3R!C或P_NC7U @ 7 |()N。”
醇>
R会话信息(基础R,无附加包):
R版本3.2.4(2016-03-10)平台:x86_64-apple-darwin13.4.0 (64位)运行于:OS X 10.11.5(El Capitan)
答案 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] ""
模式匹配字符串与我们的模式(即捕获到第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}|\"
这里,标题前的所有内容和所有双引号都被空字符串替换。