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

Regex 查找以不是下一个匹配的起始字母的字母结尾的匹配项,regex,regex-lookarounds,regex-greedy,Regex,Regex Lookarounds,Regex Greedy,简介 我有一个包含诊断代码(ICD-10)的字符串,没有任何字符分隔。我想提取所有有效的诊断代码。有效诊断代码的格式如下所示 [字母][2到4个数字之间][不是下一个匹配起始字母的可选字母] 这种模式的正则表达式是(我相信) 示例 这里有一个例子 mystring='F328AG560F33' 本例中有三个代码: 'F328A''G560''F33' 我想用str_extract_all in R这样的函数来提取这些代码(最好但不限于此) 我目前的解决方案 到目前为止,我终于想出了一个表达方式

简介

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

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

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

示例

这里有一个例子

mystring='F328AG560F33'
本例中有三个代码:

'F328A'
'G560'
'F33'

我想用str_extract_all in R这样的函数来提取这些代码(最好但不限于此)

我目前的解决方案

到目前为止,我终于想出了一个表达方式,比如:

str_extract_all(mystring,pattern='\\w\\d{2,4}\\w?(?!(\\w\\d{2,4}\\w?))')
但是,当应用于上面的示例时,它返回

"F328"  "G560F"
基本上,它忽略了第一个代码中的字母A,并且错误地将F分配给前面的代码,从而忽略了最后一个代码“F33”

问题

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

应用程序


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

您的匹配是重叠的。在这种情况下,您可以使用
str_match_all
,它允许轻松访问捕获组,并使用一个具有正向前瞻性的模式,其中包含一个捕获组:

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

详细信息

  • (?=
    -正向前瞻开始(它将在每个字符之前的每个位置和字符串末尾运行)
  • -第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"  
>库(stringr)
>res[[1]][,2]
[1] F328A“G560”F33

你有一个字母,两到四个数字,然后是一个可选字母。该可选字母(如果有)后面将只跟另一个字母;或者,换句话说,永远不会跟数字。你可以写一个否定的前瞻来捕捉这一点:

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

至少是这样。我不知道R将如何处理它。

请更新您的答案,并使用内置的格式化工具格式化您的代码示例。您能解释一下为什么您这样编写正则表达式吗?正如我在问题中所写的,我这样编写正则表达式是因为我认为我需要这样做“告诉正则表达式引擎匹配可能最长的模式,但后面没有一个有效的模式”。正如Xophmeister和Wiktor指出的,这不是正确的方法。啊,是的!我之前尝试过,但无法匹配低代表的bc。你是一个敏锐的观察者:)如果不太麻烦的话,您是否介意解释一件事:在您建议的正则表达式中,您将可选字母包装在一个非捕获组中。因此,该可选字母确实不应该被捕获。但它仍然被捕获!给了什么?@Gino_JrDataScientist非捕获组只会阻止为捕获的匹配部分创建内存缓冲区组模式。但是,这些模式仍在使用,即它们匹配的字符被添加到匹配/捕获中。在下面的模式中,在前瞻中有一个外部捕获组。这意味着
(a(?:bc)?)如果输入字符串中有
abc
,则
仍将捕获
abc
,但匹配数据对象中的
bc
将没有第二个捕获组。出于某种原因,此正则表达式还返回以数字开头的代码。例如,对于“328AG560F33”,它返回“328A”G560“F33”,我知道我没有指定有可能是无效的模式。所以这个答案对于我提出的问题是有效的。但是,Wiktor的正则表达式似乎也能很好地处理像这样的破坏模式。无论如何,谢谢你的非常好的回答!:)@Gino_JrDataScientist No,不要使用
[A-z]
.EDIT这是我的错:在我的问题中,我说一个有效模式的正则表达式是带\w的,而它应该是[a-z]的,谢谢@WiktorStribiżew!!我真的不太了解它谢谢你!这个正则表达式适用于我描述的任务。我选择这个答案是因为它似乎对指定错误的诊断代码和noise”类似标点符号。例如,对于字符串“F33%10CB1203SA12 F2·1”,它将返回“F33”“B1203S”“A12”“这正是我想要的。我只是不太明白它为什么有效。我知道你把正则表达式弄坏了,谢谢你!我想我只是需要更好地了解这项前瞻性业务。再次感谢!这个答案实际上并不完全正确:在我给出的示例中,预期结果是“F328A”“G560”“F33”,而您的演示给出了以下“F328A”“G560F”“F33”。问题是,第二个代码最后有一个额外的F。。你知道怎么解决这个问题吗?@Gino_JrDataScientist那么
F
到哪里去了?它在模式中是可选的,并且在字符串中。@Gino_JrDataScientist好的,如果可以修复,我会在一两分钟内修复它。
\w\d{2,4}(?:\w(?!\d))?