我正在尝试使用 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/