替换数字后的句号

Replace period following a digit

我遇到了一个看似简单的问题,但我找到的解决方案并不令人满意。我想用逗号替换任何句点后跟数字。例如,

strings <- c("22.222.222", "12.323", "don.t replace")

将成功转换为

[1] "22,222,222"    "12,323"        "don.t replace"

我尝试的第一个解决方案是

str_replace_all(strings,
                "(?<=\d+)\.",
                ",")

但我收到以下错误消息:

Error in stri_replace_all_regex(string, pattern, replacement, vectorize_all = vec,  : 
 Look-Behind pattern matches must have a bounded maximum length. (U_REGEX_LOOK_BEHIND_LIMIT)

当我使用

str_replace_all(strings,
            "(?<=\d{1,3})\.",
            ",")

我得到了正确的转换。但是,硬编码的 1-3 位数字不是我想要的,我不明白为什么 \d+ 不起作用但 \d{1,3} 起作用。

不需要 + 量词,您只关心匹配序列中的最后一位数字。所以只需将 \d 放在 lookbehind 中即可。

str_replace_all(strings,
                "(?<=\d)\.",
                ",")

这里不需要任何环视,因为数字是已知的子模式,您不需要任何重叠匹配。只需在数字周围使用捕获组并使用反向引用在结果中恢复它们:

> library(stringr)
> strings <- c("22.222.222", "12.323", "don.t replace")
> str_replace_all(strings, "(\d+)\.", "\1,")
[1] "22,222,222"    "12,323"        "don.t replace"

或者用基数 R gsub:

> gsub("(\d+)\.", "\1,", strings)
[1] "22,222,222"    "12,323"        "don.t replace"

regex demo

请注意 (?<=\d{1,3}) constrained-width 后视是有效的,因为 stringr 正则表达式风格是 ICU。如果 lookbehind 中的模式长度可以事先计算出来,它将起作用,因此具有最小值和最大值的限制量词可以正常工作。它不适用于 gsub 的 PCRE (perl=T) 正则表达式。无限宽度后视(内部带有 +* 量词)仅在少数几种情况下受支持:Python PyPi 正则表达式模块、.NET、RegexBuddy 工具、Vim.