简介
我有一个包含诊断代码(ICD-10)的字符串,没有任何字符分隔。我想提取所有有效的诊断代码。有效的诊断代码的格式为
[Letter] [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?))')
然而,当应用于上面的示例时,它返回
"F328" "G560F"
基本上它错过了第一个代码中的字母A,并完全错过了最后一个代码" F33"错误地将F分配给前面的代码。
问题
我做错了什么?我只想提取以不是下一个匹配开头的字母结尾的值,如果是,则匹配不应该包含该字母。
应用
这个问题非常重要,例如在挖掘未经验证的患者电子健康记录时。
答案 0 :(得分:2)
你有一个字母,两到四个数字,然后是一个可选的字母。那封可选的信件,如果它在那里,将只会跟着另一封信;或者,换句话说,从不跟随一个数字。你可以写一个负面的先行来捕捉这个:
\w\d{2,4}(?:\w(?!\d))?
这至少是works with PCRE。我不知道R将如何处理它。
答案 1 :(得分:1)
您的比赛重叠。在这种情况下,您可以使用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组结束)
- Lookahead end。R demo:
> 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"