我有一个如下所示的数据集。我想用 1 替换两个 1 之间的所有点,如所需的结果所示。 我可以用
regex
中的 R
来完成此操作吗?
我尝试过:
regexpr("^1\\.1$", my.data$my.string, perl = TRUE)
这是c#中的解决方案
感谢您的任何建议。
my.data <- read.table(text='
my.string state
................1...............1. A
......1..........................1 A
.............1.....2.............. B
......1.................1...2..... B
....1....2........................ B
1...2............................. C
..........1....................1.. C
.1............................1... C
.................1...........1.... C
........1....2.................... C
......1........................1.. C
....1....1...2.................... D
......1....................1...... D
.................1...2............ D
', header = TRUE, na.strings = 'NA', stringsAsFactors = FALSE)
desired.result <- read.table(text='
my.string state
................11111111111111111. A
......1111111111111111111111111111 A
.............1.....2.............. B
......1111111111111111111...2..... B
....1....2........................ B
1...2............................. C
..........1111111111111111111111.. C
.111111111111111111111111111111... C
.................1111111111111.... C
........1....2.................... C
......11111111111111111111111111.. C
....111111...2.................... D
......1111111111111111111111...... D
.................1...2............ D
', header = TRUE, na.strings = 'NA', stringsAsFactors = FALSE)
下面是使用
gsub
与 \G
功能和环视断言的选项。
> gsub('(?:\\G(?!^)|\\.*1(?=\\.+1))\\K\\.', '1', my.data$my.string, perl = TRUE)
# [1] "................11111111111111111." "......1111111111111111111111111111"
# [3] ".............1.....2.............." "......1111111111111111111...2....."
# [5] "....1....2........................" "1...2............................."
# [7] "..........1111111111111111111111.." ".111111111111111111111111111111..."
# [9] ".................1111111111111...." "........1....2...................."
# [11] "......11111111111111111111111111.." "....111111...2...................."
# [13] "......1111111111111111111111......" ".................1...2............"
\G
特征是一个锚点,可以在两个位置之一进行匹配;字符串位置的开头或最后一个匹配的结尾位置。由于您似乎想避免字符串位置开头的点,因此我们使用环视断言 \G(?<!^)
来排除字符串的开头。
\K
转义序列会重置报告的匹配的起点,并且不再包含任何先前消耗的字符。
您可以在此处找到解释正则表达式的整体细分。
使用
gsubfn
,第一个参数是一个正则表达式,它匹配 1 和 1 之间的字符并捕获后者。 第二个参数是一个函数,以公式表示法表示,它使用 gsub
将捕获的字符串中的每个字符替换为 1:
library(gsubfn)
transform(my.data, my.string = gsubfn("1(.*)1", ~ gsub(".", 1, x), my.string))
如果字符串中可以有多对 1,则使用
"1(.*?)1"
作为正则表达式。
可视化这里的正则表达式很简单,可以直接理解,但这里有一个debuggex可视化anwyays:
1(.*)1
这是一个选项,它使用相对简单的正则表达式和
gregexpr()
、regmatches()
和 regmatches<-()
的标准组合来识别、提取、操作,然后替换与该正则表达式匹配的子字符串。
## Copy the character vector
x <- my.data$my.string
## Find sequences of "."s bracketed on either end by a "1"
m <- gregexpr("(?<=1)\\.+(?=1)", x, perl=TRUE)
## Standard template for operating on and replacing matched substrings
regmatches(x,m) <- sapply(regmatches(x,m), function(X) gsub(".", "1", X))
## Check that it worked
head(x)
# [1] "................11111111111111111." "......1111111111111111111111111111"
# [3] ".............1.....2.............." "......1111111111111111111...2....."
# [5] "....1....2........................" "1...2............................."