用于替换列表定界符和字符串结尾的可变长度否定后视
Variable-length negative look-behind for replacing list delimiters and the string end
我希望在分隔值字符串(包括最后一个)中缺少索引的值之后插入索引。
s <- "Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)"
gsub("(?<!\[\d\])(;|$)", "\[0\]\2", s, perl=TRUE)
这段代码让我缺少定界符:
"Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.)[0]Simmons, AJ(Simmons, A. J.)[0]Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[0]"
代码类似地处理最后一个值已经有索引的情况:
s <- "Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[3]"
这次捐赠(仍缺少分隔符):
"Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.)[0]Simmons, AJ(Simmons, A. J.)[0]Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[3]"
我需要找回丢失的分隔符,例如第一种情况:
"Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.)[0];Simmons, AJ(Simmons, A. J.)[0];Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[0]"
此外,我希望代码也能处理多于一位数的索引,即 10、100 等(可变长度),例如:
s <- "Dee, DP(Dee, D. P.)[10];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)"
或
s <- "Dee, DP(Dee, D. P.)[10];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[3]"
在您的替换模式中,</code> 指的是不存在的第 2 组。 <code>(?<!...)
是一个负面回顾,与捕获组不同,它不会强制正则表达式引擎为其匹配值分配任何特殊内存缓冲区。
您必须使用 </code>,而不是 <code>
。
要解决后视中的可变宽度模式,您可以使用带有 SKIP-FAIL 动词的 PCRE 模式的两步方法:
s <- gsub("\[\d+];(*SKIP)(*F)|(;)", "[0]\1", s, perl=TRUE)
sub("(?s)^(?!.*\[\d+]$)(.*)", "\1[0]", s, perl=TRUE)
见regex demo #1 / regex demo #2 and the R demo online
模式 #1 详细信息
\[\d+];(*SKIP)(*F)
- [
, 1+ 位, ]
然后 ;
; (*SKIP)(*F)
从整体匹配内存缓冲区中丢弃此匹配文本,并继续从失败的位置搜索正则表达式模式
|
- 或
(;)
- 第 1 组(替换模式中的 </code>):一个 <code>;
字符。
模式#2
(?s)
- 转换 dotall 模式,以便 .
可以匹配 TRE 正则表达式中的任何字符(由 sub
使用而没有 perl=TRUE
)
^
- 字符串开头
(?!.*\[\d+]$)
- 否定前瞻,确保字符串 末尾没有 [
、1+ 位和 ]
(.*)
- 所有字符串都在第 1 组中捕获。
或者,如果您可以使用 stringr
并且您知道位数少于某个值,例如 100,您可以利用此 constrained-width 后视 ICU图书馆特色:
stringr::str_replace_all(s, "(?<!\[\d{1,100}])(;|$)", "[0]\1")
这里,(?<!\[\d{1,100}])
匹配字符串中不紧跟[
的位置,1到100位,然后是]
.
我希望在分隔值字符串(包括最后一个)中缺少索引的值之后插入索引。
s <- "Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)"
gsub("(?<!\[\d\])(;|$)", "\[0\]\2", s, perl=TRUE)
这段代码让我缺少定界符:
"Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.)[0]Simmons, AJ(Simmons, A. J.)[0]Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[0]"
代码类似地处理最后一个值已经有索引的情况:
s <- "Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[3]"
这次捐赠(仍缺少分隔符):
"Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.)[0]Simmons, AJ(Simmons, A. J.)[0]Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[3]"
我需要找回丢失的分隔符,例如第一种情况:
"Dee, DP(Dee, D. P.)[1];Uppala, SM(Uppala, S. M.)[0];Simmons, AJ(Simmons, A. J.)[0];Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[0]"
此外,我希望代码也能处理多于一位数的索引,即 10、100 等(可变长度),例如:
s <- "Dee, DP(Dee, D. P.)[10];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)"
或
s <- "Dee, DP(Dee, D. P.)[10];Uppala, SM(Uppala, S. M.);Simmons, AJ(Simmons, A. J.);Kobayashi, S(Kobayashi, S.)[2];Andrae, U(Andrae, U.)[3]"
在您的替换模式中,</code> 指的是不存在的第 2 组。 <code>(?<!...)
是一个负面回顾,与捕获组不同,它不会强制正则表达式引擎为其匹配值分配任何特殊内存缓冲区。
您必须使用 </code>,而不是 <code>
。
要解决后视中的可变宽度模式,您可以使用带有 SKIP-FAIL 动词的 PCRE 模式的两步方法:
s <- gsub("\[\d+];(*SKIP)(*F)|(;)", "[0]\1", s, perl=TRUE)
sub("(?s)^(?!.*\[\d+]$)(.*)", "\1[0]", s, perl=TRUE)
见regex demo #1 / regex demo #2 and the R demo online
模式 #1 详细信息
\[\d+];(*SKIP)(*F)
-[
, 1+ 位,]
然后;
;(*SKIP)(*F)
从整体匹配内存缓冲区中丢弃此匹配文本,并继续从失败的位置搜索正则表达式模式|
- 或(;)
- 第 1 组(替换模式中的</code>):一个 <code>;
字符。
模式#2
(?s)
- 转换 dotall 模式,以便.
可以匹配 TRE 正则表达式中的任何字符(由sub
使用而没有perl=TRUE
)^
- 字符串开头(?!.*\[\d+]$)
- 否定前瞻,确保字符串 末尾没有 (.*)
- 所有字符串都在第 1 组中捕获。
[
、1+ 位和 ]
或者,如果您可以使用 stringr
并且您知道位数少于某个值,例如 100,您可以利用此 constrained-width 后视 ICU图书馆特色:
stringr::str_replace_all(s, "(?<!\[\d{1,100}])(;|$)", "[0]\1")
这里,(?<!\[\d{1,100}])
匹配字符串中不紧跟[
的位置,1到100位,然后是]
.