r - 获取r中字符串中模式的重叠位置
问题描述
客观的:
在允许重叠的字符串中查找模式的所有位置(开始和结束索引)。
方法:
这些stri_locate_all_*
函数返回一个模式在字符串中的位置列表。该列表包括包含每个匹配位置的开始索引和结束索引的矩阵。这对我的目的很方便。
对于固定模式,以下方法效果很好:
s <- "---"
pattern <- "--"
stri_locate_all_fixed(s, pattern, overlap = TRUE)
[[1]]
start end
[1,] 1 2
[1,] 2 3
字符串“s”中出现了两次模式“--”。第一个从 s 的索引 1 开始,到索引 2 结束;第二个从索引 2 开始,到索引 3 结束。
--
-
---
但是,在我的情况下,模式可能包含多个允许的字符(以任何顺序或组合),并且模式的长度可能会改变。因此,“正则表达式”似乎比“固定”更合适。
考虑模式长度为 2,由“-”和“1”的任意组合(即“-1”、“1-”、“--”、“11”)和stri_locate_all_regex
.
pattern <- "[1|-]{2}"
s <- "-1-"
stri_locate_all_regex(s, pattern)
[[1]]
start end
[1,] 1 2
请注意,stri_locate_all_regex
不使用重叠属性,因此如果我想捕获重叠,则必须调整模式。
根据各种消息来源,我需要在我的正则表达式中添加一个积极的前瞻性。
pattern <- "(?=[1|-]{2})"
此模式应该(并且在regex101 测试仪上进行测试时确实如此)找到模式的重叠出现。
但是,当使用stri_locate_all_regex
返回的值不是我想要的。
stri_locate_all_regex("---", "(?=[1|-]{2})")
[[1]]
start end
[1,] 1 0
[2,] 2 1
在这里,该函数正确识别出存在两个匹配项并记录了起始索引,但结束索引低于起始索引。
Stringi文档指出:
“对于 stri_locate_*_regex,如果匹配长度为 0,则 end 将比 start 少一个字符。”
这表明匹配长度为 0;正则表达式“lookarounds”的描述进一步支持了这一观察:
“Lookahead 和lookbehind,统称为‘lookaround’,是零长度断言……lookaround 实际上匹配字符,但随后放弃匹配,只返回结果:匹配或不匹配。”
所以,我的问题似乎在于使用积极的前瞻断言,该断言似乎在“开始”索引处返回零长度位置。
我的提炼问题:
- 是否有更好的正则表达式方法来捕获重叠(非零长度)匹配?或者,
- 是否有比stri_locate_all_regex
实现所需输出更好的 r 函数(字符串中模式匹配的所有开始/结束位置的列表)
谢谢!
解决方案
您可以将gregexpr
PCRE 正则表达式与包含整个正向前瞻模式的捕获组一起使用:
pattern <- "(?=([1-]{2}))"
s <- "-1-"
res <- gregexpr(pattern, s, perl=TRUE)
starts <- attr(res[[1]],'capture.start')
lengths <- attr(res[[1]],'capture.length')
ends <- starts + lengths - 1
df_positions <- do.call(rbind, Map(data.frame, start=starts, end=ends, length=lengths))
df_positions
输出:
start end length
1 1 2 2
2 2 3 2
查看R 演示
推荐阅读
- bookmarklet - 推送时显示的书签
- azure - 从 PowerApp(或逻辑应用)调用受 AAD 保护的 Azure 函数
- performance - DaCe 中的空 SDFG
- flutter - 如何使用 Flutter_ffmpeg 在 Flutter 中为视频添加水印
- adaptive-cards - 可操作的电子邮件开发人员仪表板不起作用
- vba - 是否有隐藏多列空行的代码?
- python - 在 Python/Pyspark 中获取每月计数的更有效方法
- r - 基于 R 中重叠的多个条件进行聚合
- html - 图片和下拉菜单不对齐
- javascript - 当 React 中父项中的值更改时更新子组件