r语言 - 正则表达式奇怪的结果



Code

gsub('101', '111', '110101101')
#[1] "111101111"

有谁知道为什么输入中的第二个 0 没有被替换成输出中的 1? 我正在寻找字符串中的模式 101 并将其替换为字符串 111。稍后,我希望将较长的子序列转换为 1 的序列,例如 10001 到 11111。

您可以使用前瞻?=

其工作方式是q(?=u)匹配后跟 u 的 q,而不使 u 成为匹配的一部分。

例:

gsub('10(?=1)', '11', '110101101', perl=TRUE);
// Output: 111111111

编辑:您需要在perl模式下使用gsub才能使用前瞻

因为它不以递归方式工作

gsub('101', '111', '110101101'( 在找到匹配项时将第三个字符串分开。因此,它找到第一个 101 及其左侧的 01101。想想吧。如果它替换"递归",像 gsub('11', '111', '11'(这样的东西会返回一个无限的字符串 '1' 并中断。它不会签入已经"替换"的文本。

这是因为当 R 首次检测到 1 101 01101时,它会将下一个 0 视为1101011 01 中的011

似乎您只想将"0"替换为"1"。然后你可以只使用gsub('0', '1', '110101101')

稍后,

我希望将较长的子序列转换为 1 的序列,例如 10001 到 11111。

希望 R 提供了一种基于匹配的子字符串生成替换字符串的方法。(这是一个常见功能。

如果是这样,请搜索10+,并让替换字符串生成器创建一个由等于匹配长度的1字符组成的字符串。(例如,如果匹配100,则替换为111。如果匹配1000,请替换为1111。等(

我根本不了解R。以下是在其他一些语言中完成此操作的方法,以防有帮助:

Perl:

$s =~ s{10+}{ "1" x length($&) }ger

蟒:

re.sub(r'10+', lambda match: '1' * len(match.group()), s)

JavaScript:

s.replace(/10+/g, function(match) { return '1'.repeat(match.length) })

JavaScript (ES6(:

s.replace(/10+/g, match => '1'.repeat(match.length))

根据 OP

稍后我希望将较长的子序列转换为 1 的序列, 如 10001 到 11111。

如果我理解正确,最终目标是将连续0的任何子序列替换为相同数量的1,如果它们被两侧的1包围。

在 R 中,这可以通过stringr包中的str_replace_all()函数来实现。为了演示和测试,input向量包含一些边缘情况,其中0的子串没有1包围。

input <- c("110101101",
"11010110001",
"110-01101",
"11010110000",
"00010110001")
library(stringr)
str_replace_all(input, "(?<=1)0+(?=1)", function(x) str_dup("1", str_length(x)))
[1] "111111111"   "11111111111" "110-01111"   "11111110000" "00011111111"

正则表达式"(?<=1)0+(?=1)"使用(?<=1)后面的视图以及(?=1)的前瞻来确保要替换的子序列0+1包围。因此,0的前导和尾随子序列不会被替换。

替换由一个函数计算,该函数返回与要替换的0子序列长度相同的1子序列。

最新更新