查找以不是下一个匹配项的起始字母的字母结尾的匹配项

Find matches ending with a letter that is not a starting letter of the next match

简介

我有一个包含诊断代码(ICD-10)的字符串,没有任何字符分隔。我想提取所有有效的诊断代码。有效诊断代码的形式为

[字母][2到4个数字之间][不是下一个匹配起始字母的可选字母]

这个模式的正则表达式是(我相信)

\w\d{2,4}\w?

例子

这是一个例子

mystring='F328AG560F33'

在这个例子中有三个代码:

'F328A' 'G560' 'F33'

我想用 R 中的 str_extract_all 之类的函数提取这些代码(最好但不完全)

我目前的解决方案

到目前为止,我设法想出了如下表达式:

str_extract_all(mystring,pattern='\w\d{2,4}\w?(?!(\w\d{2,4}\w?))')

然而,当应用于上面的示例时 returns

"F328"  "G560F"

基本上它错过了第一个代码中的字母 A,并且由于错误地将 F 分配给前面的代码而完全错过了最后一个代码 "F33"。

问题

我做错了什么?我只想提取以不是下一个匹配项开头的字母结尾的值,如果是,则匹配项不应包含该字母。

申请

这个问题非常重要,例如在挖掘未经验证的患者电子健康记录时。

您的比赛有重叠。在这种情况下,您可以使用 str_match_all 允许轻松访问捕获组,并使用包含内部捕获组的正前瞻模式:

(?i)(?=([A-Z]\d{2,4}(?:[A-Z](?!\d{2,4}))?))

regex demo

详情

  • (?= - 一个积极的先行开始(它将在每个字符之前和字符串末尾的每个位置 运行
  • ( - 第 1 组开始
    • [A-Z] - 一个字母(如果你使用不区分大小写的修饰符(?i),它将不区分大小写)
    • \d{2,4} - 2 到 4 位数
    • (?: - 可选的非捕获组开始:
      • [A-Z] - 一封信
      • (?!\d{2,4}) - 后面没有 2 到 4 位数字
    • )? - 可选的非捕获组结束
  • ) - 第 1 组结束
  • ) - 前瞻结束。

R 演示:

> library(stringr)
> res <- str_match_all("F328AG560F33", "(?i)(?=([A-Z]\d{2,4}(?:[A-Z](?!\d{2,4}))?))")
> res[[1]][,2]
[1] "F328A" "G560"  "F33"  

你有一个字母,二到四个数字,然后是一个可选的字母。该可选字母(如果存在)只会跟随另一个字母;或者,换句话说,从不跟数字。你可以写一个负面的前瞻来捕捉这个:

\w\d{2,4}(?:\w(?!\d))?

这个至少works with PCRE。不知道R会怎么处理。