我正在尝试使用str分支
和perl正则表达式在R中拆分字符串。该字符串由用句点或连字符分隔的各种字母数字标记组成,例如"WXYZ-AB-A4K7-01A-13B-J29Q-10"
。我想拆分字符串:
[“01”,“a”]
(但不拆分“012A”
、“B1A”
、“0A1”
、和“01A2”
)例如,"WXYZ-AB-A4K7-01A-13B-J29Q-10"
应该产生["WXYZ","AB","01","A","13","B","J29Q","10"]
。
我当前的正则表达式是((?
此外,备选方案的两部分,<代码>(?
#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"
多亏了Rich Scriven和Jota,我才解决了这个问题。每次strsplit找到匹配项时,它都会删除匹配项及其左侧的所有内容,然后再查找下一个匹配项。这意味着,当lookbehind与之前的匹配重叠时,依赖lookbehind的正则表达式可能无法按预期工作。在我的例子中,令牌之间的连字符在匹配时被删除,这意味着第二个正则表达式无法使用它们来检测令牌的开头:
#first match found
"WXYZ-AB-A4K7-01A-13B-J29Q-10"
^
#match + left removed
"AB-A4K7-01A-13B-J29Q-10"
#further matches found and removed
"01A-13B-J29Q-10"
#second regex fails to match because of missing hyphen in lookbehind:
#((?<=[-.]\\d{2})(?=[A-Z][-.]))
# ^^^^^^^^
"01A-13B-J29Q-10"
#algorithm continues
"13B-J29Q-10"
根据Jota的建议,这是通过替换[.-]
类来用边界锚点检测Lookback中令牌的边缘来修复的:
> strsplit("WXYZ-AB-A4K7-01A-13B-J29Q-10", "[-.]|(?<=\\b\\d{2})(?=[A-Z]\\b)", perl=T)
[[1]]
[1] "WXYZ" "AB" "A4K7" "01" "A" "13" "B" "J29Q" "10"
您可以使用正向前瞻的消费版本(匹配重置运算符),以确保strsplit在R中正确工作,并避免在正向前瞻中使用反向前瞻的问题。
"(?<![^.-])\\d{2}\\K(?=[A-Z](?:[.-]|$))|[.-]"
在线查看R演示(以及此处的正则表达式演示)。
strsplit("XYZ-02-01C-33D-2285", "(?<![^.-])\\d{2}\\K(?=[A-Z](?:[.-]|$))|[.-]", perl=TRUE)
## => [[1]]
## [1] "XYZ" "02" "01" "C" "33" "D" "2285"
strsplit("WXYZ-AB-A4K7-01A-13B-J29Q-10", "(?<![^.-])\\d{2}\\K(?=[A-Z](?:[.-]|$))|[.-]", perl=TRUE)
## => [[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的评论可能更好,因为它们只有一个函数调用。
我要匹配以下字符串: 包含unicode空格(不要问我为什么)<代码>/,\s*,/u在regex101中工作正常。 但是(?u),\s*,“在clojure中不起作用: 为什么会失败?
我有一个包含特殊字符的字符串列表 它像这样工作得很好 输出 安得拉邦 卡纳塔克邦 当我使用过滤器来做这件事时 它不起作用!我把名单原封不动地拿回来了。 我期待着这样一份清单['Andhra Pradesh','Karnataka'] 我希望从字符串列表中删除特殊字符,如,和
密码不能匹配或包含姓氏。 密码必须至少包含1个特殊字符。 密码必须至少包含1个数字字符。 密码必须至少包含2个字母字符。 密码必须至少包含1个大写字母。 密码不能匹配或包含用户ID。 密码不能匹配或包含名字。 密码不能包含以下字符:! 密码不得超过25个字符。 密码长度必须至少为8个字符。 密码必须至少包含1个小写字母。 这些是
问题内容: 我有一个正则表达式: 这应该与该字符串匹配并返回三个捕获(根据Rubular) 这是我的代码: 当有三个时,此打印输出1(组),所以我只能这样做,只会返回32。 问题答案: 调用查找匹配的 下一个 实例,如果没有更多实例,则返回false。尝试调用它三次,看看是否有所有预期的组。 为了澄清,正在尝试 在正则表达式中 找到第一个组 表达式 。您的正则表达式中只有一个这样的组表达式,因此永
正则表达式非常简单: 这在Neo4j服务器web控制台中有效。我收到了预期的结果。 当我通过Java使用REST接口时,我必须将regex更改为:(添加了反斜杠)。我不明白为什么,但它确实有效(再次返回了预期结果)。 相同的正则表达式不适用于嵌入式Neo4j: 请注意 不会显示在错误日志中(至少在 Intellij 控制台上)。 更糟糕的是< code > "(?我)。* \ \ baaaaaaa
问题内容: 我正在尝试使用以下程序使用正则表达式删除字符串中的某些单词。它可以正确删除,但只考虑大小写。如何使其不区分大小写。我坚持使用方法,但是没有用。 输出: 问题答案: 您需要将模式中要区分大小写的部分放在 前面 : 看见 我已将要删除的关键字周围的空格替换为单词边界()。之所以出现问题,是因为可能有两个关键字一个接一个地被一个空格隔开。 如果仅当关键字被 空格 包围时才想删除它们,则可以使