正则表达式可以单独工作,但在 strsplit 中一起使用时则不起作用

标签 r regex pcre regex-lookarounds strsplit

我正在尝试使用 strsplit 在 R 中分割字符串和一个 Perl 正则表达式。该字符串由各种字母数字标记组成,以句点或连字符分隔,例如 "WXYZ-AB-A4K7-01A-13B-J29Q-10" 。我想分割字符串:

  • 连字符出现的位置。
  • 无论出现句点的位置。
  • 位于 token 的第二个和第三个字符之间,长度恰好为 3 个字符,由 2 个数字后跟 1 个大写字母组成,例如 "01A"产生["01", "A"] (但 "012A""B1A""0A1""01A2" 未拆分)。

例如,"WXYZ-AB-A4K7-01A-13B-J29Q-10"应该产生 ["WXYZ", "AB", "01", "A", "13", "B", "J29Q", "10"] .

我当前的正则表达式是 ((?<=[-.]\\d{2})(?=[A-Z][-.]))|[.-]它在 this online regex tester 中完美运行。

此外,替代方案的两个部分 ((?<=[-.]\\d{2})(?=[A-Z][-.]))[.-] ,当它们单独使用时,两者都用于按照 R 中的预期分割字符串:

#correctly splits on periods and hyphens
strsplit("WXYZ-AB-A4K7-01A-13B-J29Q-10", "[.-]", perl=T)
[[1]]
[1] "WXYZ" "AB"   "A4K7" "01A"  "13B"  "J29Q" "10"

#correctly splits tokens where a letter follows two digits
strsplit("WXYZ-AB-A4K7-01A-13B-J29Q-10", "((?<=[-.]\\d{2})(?=[A-Z][-.]))", perl=T)
[[1]]
[1] "WXYZ-AB-A4K7-01" "A-13"            "B-J29Q-10"

但是当我尝试使用替代方案组合它们时,第二个正则表达式停止工作,并且字符串仅按句点和连字符分割:

#only second alternative is used
strsplit("WXYZ-AB-A4K7-01A-13B-J29Q-10", "((?<=[-.]\\d{2})(?=[A-Z][-.]))|[.-]", perl=T)
[[1]]
[1] "WXYZ" "AB"   "A4K7" "01A"  "13B"  "J29Q" "10"

为什么会发生这种情况?是我的正则表达式有问题,还是 strsplit 有问题?我怎样才能实现预期的行为?

期望的输出:

## [[1]]
## [1] "WXYZ" "AB"   "A4K7" "01"   "A"    "13"   "B"    "J29Q" "10"

最佳答案

另一种方法可以让您不必考虑 strsplit 算法的工作原理,即使用带有 gsub 的原始正则表达式在所有右侧插入一个简单的分割字符位置,然后使用 strsplit 进行简单的拆分。

strsplit(
    gsub("((?<=[-.]\\d{2})(?=[A-Z][-.]))|[.-]", "-", x, perl = TRUE),
    "-", 
    fixed = TRUE)
#[[1]]
#[1] "XYZ"  "02"   "01"   "C"    "33"   "D"    "2285"

当然,RichScriven 的回答和 Wiktor Stribiżew 的评论可能更好,因为它们只有一个函数调用。

关于正则表达式可以单独工作,但在 strsplit 中一起使用时则不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41862414/

相关文章:

r - 如何根据条件加入和标记

r - R中是否有一个函数可以用行标准平均值替换NA?

regex - gitk中正则表达式的格式是什么?

R 中的 readRDS(文件)

r - 根据向量中的值从数据框中选择行

ios - 无法使用正则表达式获取全名

regex - 持续模式匹配来识别 SQL 子句

php - preg_replace 带有/e修饰符的代码评估

javascript - ANTLR PCRE 文法转 JS 目标

php - 正则表达式帮助 - Wordpress (search-regex)