将括号添加到具有给定条件的字符串
Add parentheses to a string with a given condition
我想在条件下为以下字符串添加括号。数字由两部分组成:“Id - subId”,当有多个subId时我想加括号。
sample_string1 = "376-12~23, 28, 32, 35, 37,376-1"
sample_string2 = "391-1~8, 391-22~23"
sample_string3 = "391-10~21, 391-24, 27, 29"
这些是我想要的结果。
desire_string1 = "376-(12~23, 28, 32, 35, 37),376-1"
desire_string2 = "391-(1~8), 391-(22~23)"
desire_string3 = "391-(10~21), 391-(24, 27, 29)"
我该怎么做?提前致谢
这是一个相当复杂的正则表达式问题。老实说,我建议您不要使用此解决方案,而是分离出您想要的变量并使它们整洁。
但是,你问了这个问题,所以这里有一个正则表达式的答案。我使用了 stringr
包,因为我发现它比 grep
.
更容易和更具可读性
正则表达式分解如下:
(?<=-)
- 正向后查找 - 但不捕获它
(\d+[\~\,] ?[^\-]*)+
- 捕获多个 1 位或多个数字,后跟一个 ~ 或一个 ,然后可能是一个 space 后跟 0 个或多个不是 - 的字符。捕获一个长度为 1 个或多个这些字符组合的组。
((?=, *\d+-)|$)
- 在上一次捕获之后查找包含 a 、一些 space 和长度为 1 或更多数字的数字的前瞻性,或捕获行尾字符。
replacement= "(\1)"
- 将您捕获的结果替换为(然后是您捕获的第一组)
library(stringr)
sample_string1 = "376-12~23, 28, 32, 35, 37,376-1"
sample_string2 = "391-1~8, 391-22~23"
sample_string3 = "391-10~21, 391-24, 27, 29"
# (?!u)
ss1 <- str_replace_all(sample_string1,
"(?<=-)(\d+[\~\,] ?[^\-]*)+((?=, *\d+-)|$)",
replacement= "(\1)")
ss1
# "376-(12~23, 28, 32, 35, 37),376-1"
ss2 <- str_replace_all(sample_string2,
"(?<=-)(\d+[\~\,] ?[^\-]*)+((?=, *\d+-)|$)",
replacement= "(\1)")
ss2
# "391-(1~8), 391-(22~23)"
ss3 <- str_replace_all(sample_string3,
"(?<=-)(\d+[\~\,] ?[^\-]*)+((?=, *\d+-)|$)",
replacement= "(\1)")
ss3
# "391-(10~21), 391-(24, 27, 29)"
产生正确输出的正则表达式是:
(?:(\d+-)((?:\d+~\d+|(?:,?\s*\d+){2,})+)(?=,\s*\d+-|\"))
演示:https://regex101.com/r/QHDCMd/1/
(\d+-)
匹配 ID 和破折号
\d+~\d+
匹配子范围或...
(?:,?\s*\d+){2,}
至少两个补贴
(?=,\s*\d+-|\")
积极预测下一个 ID 或收盘价
我想在条件下为以下字符串添加括号。数字由两部分组成:“Id - subId”,当有多个subId时我想加括号。
sample_string1 = "376-12~23, 28, 32, 35, 37,376-1"
sample_string2 = "391-1~8, 391-22~23"
sample_string3 = "391-10~21, 391-24, 27, 29"
这些是我想要的结果。
desire_string1 = "376-(12~23, 28, 32, 35, 37),376-1"
desire_string2 = "391-(1~8), 391-(22~23)"
desire_string3 = "391-(10~21), 391-(24, 27, 29)"
我该怎么做?提前致谢
这是一个相当复杂的正则表达式问题。老实说,我建议您不要使用此解决方案,而是分离出您想要的变量并使它们整洁。
但是,你问了这个问题,所以这里有一个正则表达式的答案。我使用了 stringr
包,因为我发现它比 grep
.
正则表达式分解如下:
(?<=-)
- 正向后查找 - 但不捕获它
(\d+[\~\,] ?[^\-]*)+
- 捕获多个 1 位或多个数字,后跟一个 ~ 或一个 ,然后可能是一个 space 后跟 0 个或多个不是 - 的字符。捕获一个长度为 1 个或多个这些字符组合的组。
((?=, *\d+-)|$)
- 在上一次捕获之后查找包含 a 、一些 space 和长度为 1 或更多数字的数字的前瞻性,或捕获行尾字符。
replacement= "(\1)"
- 将您捕获的结果替换为(然后是您捕获的第一组)
library(stringr)
sample_string1 = "376-12~23, 28, 32, 35, 37,376-1"
sample_string2 = "391-1~8, 391-22~23"
sample_string3 = "391-10~21, 391-24, 27, 29"
# (?!u)
ss1 <- str_replace_all(sample_string1,
"(?<=-)(\d+[\~\,] ?[^\-]*)+((?=, *\d+-)|$)",
replacement= "(\1)")
ss1
# "376-(12~23, 28, 32, 35, 37),376-1"
ss2 <- str_replace_all(sample_string2,
"(?<=-)(\d+[\~\,] ?[^\-]*)+((?=, *\d+-)|$)",
replacement= "(\1)")
ss2
# "391-(1~8), 391-(22~23)"
ss3 <- str_replace_all(sample_string3,
"(?<=-)(\d+[\~\,] ?[^\-]*)+((?=, *\d+-)|$)",
replacement= "(\1)")
ss3
# "391-(10~21), 391-(24, 27, 29)"
产生正确输出的正则表达式是:
(?:(\d+-)((?:\d+~\d+|(?:,?\s*\d+){2,})+)(?=,\s*\d+-|\"))
演示:https://regex101.com/r/QHDCMd/1/
(\d+-)
匹配 ID 和破折号\d+~\d+
匹配子范围或...(?:,?\s*\d+){2,}
至少两个补贴(?=,\s*\d+-|\")
积极预测下一个 ID 或收盘价