使用定界符拆分字符串,除非在括号中,并保留定界符
Split string with delimiter except when in parentheses, and keep the delimiter
我想拆分任意字符串,例如
x <- "(((K05708+K05709+K05710+K00529) K05711),K05712),K05713 K05714 K02554"
# [1] "(((K05708+K05709+K05710+K00529) K05711),K05712),K05713 K05714 K02554"
at delimiter(s)(这里是一个 space 和一个逗号)除非它们在括号内,并且还保留分隔符作为输出的一部分
[[1]]
[1] "(((K05708+K05709+K05710 K00529) K05711),K05712)"
[2] ",K05713" " K05714"
[4] " K02554"
这个例子几乎是直接从 IgnacioF 的 (https://whosebug.com/users/5935889/ignaciof) post
,因为这个例子仅仅是对它的扩展,而且在知道的人手中,解决方案也可以。
在单个分隔符的情况下,我可以将其粘贴到输出向量元素中,但同时使用多个分隔符时,它们的身份在拆分时会丢失,所以据我所知这是行不通的。
我试图找到使用先行和对原始 post 解决方案的其他修改来保持定界符的解决方案,但主要是因为我不了解其解决方案而徒劳无功。
你可以使用
x <- "(((K05708+K05709+K05710+K00529) K05711),K05712),K05713 K05714 K02554"
rx <- "(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|(?<=[^\s,])(?=[\s,])"
strsplit(x, rx, perl=TRUE)
# => [[1]]
# => [1] "(((K05708+K05709+K05710+K00529) K05711),K05712)" ",K05713"
# => [3] " K05714" " K02554"
这里的模式是(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|(?<=[^\s,])(?=[\s,])
,参见its demo online。
详情:
(\((?:[^()]++|(?1))*\))(*SKIP)(*F)
- 第 1 组匹配呈现平衡括号子串的子串:\(
匹配 (
,(?:[^()]++|(?1))*
匹配零个或多个(*
) (
和 )
以外的 1+ 个字符的序列(参见 [^()]++
)或整个第 1 组的整个模式(参见子路由调用 (?1)
),然后 \)
匹配文字 )
并且 (*SKIP)(*F)
使正则表达式丢弃整个匹配的文本,同时将正则表达式索引保留在该匹配的末尾,并继续寻找下一个匹配项
|
- 或
(?<=[^\s,])(?=[\s,])
- 空格和逗号以外的字符与空格或逗号字符之间的位置。
我想拆分任意字符串,例如
x <- "(((K05708+K05709+K05710+K00529) K05711),K05712),K05713 K05714 K02554"
# [1] "(((K05708+K05709+K05710+K00529) K05711),K05712),K05713 K05714 K02554"
at delimiter(s)(这里是一个 space 和一个逗号)除非它们在括号内,并且还保留分隔符作为输出的一部分
[[1]]
[1] "(((K05708+K05709+K05710 K00529) K05711),K05712)"
[2] ",K05713" " K05714"
[4] " K02554"
这个例子几乎是直接从 IgnacioF 的 (https://whosebug.com/users/5935889/ignaciof) post
在单个分隔符的情况下,我可以将其粘贴到输出向量元素中,但同时使用多个分隔符时,它们的身份在拆分时会丢失,所以据我所知这是行不通的。
我试图找到使用先行和对原始 post 解决方案的其他修改来保持定界符的解决方案,但主要是因为我不了解其解决方案而徒劳无功。
你可以使用
x <- "(((K05708+K05709+K05710+K00529) K05711),K05712),K05713 K05714 K02554"
rx <- "(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|(?<=[^\s,])(?=[\s,])"
strsplit(x, rx, perl=TRUE)
# => [[1]]
# => [1] "(((K05708+K05709+K05710+K00529) K05711),K05712)" ",K05713"
# => [3] " K05714" " K02554"
这里的模式是(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|(?<=[^\s,])(?=[\s,])
,参见its demo online。
详情:
(\((?:[^()]++|(?1))*\))(*SKIP)(*F)
- 第 1 组匹配呈现平衡括号子串的子串:\(
匹配(
,(?:[^()]++|(?1))*
匹配零个或多个(*
)(
和)
以外的 1+ 个字符的序列(参见[^()]++
)或整个第 1 组的整个模式(参见子路由调用(?1)
),然后\)
匹配文字)
并且(*SKIP)(*F)
使正则表达式丢弃整个匹配的文本,同时将正则表达式索引保留在该匹配的末尾,并继续寻找下一个匹配项|
- 或(?<=[^\s,])(?=[\s,])
- 空格和逗号以外的字符与空格或逗号字符之间的位置。