【问题标题】:How to use Regex to match discontinuous strings如何使用正则表达式匹配不连续的字符串
【发布时间】:2017-10-26 18:36:05
【问题描述】:

这个问题对其他人来说可能很简单,但我是RegEx 和这个论坛的新手,无法在任何地方找到答案。

我有一些电子邮件进入 Microsoft Outlook,通常如下所示:


病人:史密斯,简

MRN:12345678

遭遇号:1234567890

相遇日期:2017 年 4 月 11 日 12:00AM

部门:神经学

中心:头痛

位置:主校区

就诊类型:新的神经性头痛

参加物理:JONES,MARY


我想让 Outlook 在收到每封电子邮件时对其进行检查,选择其主题行表明它们具有相关信息的电子邮件,然后提取 MRN、患者姓氏、患者名字和遇到日期。

当有新邮件到达时,我的模块会运行以下 Sub:

Public Sub ProcessImatchKpEmails(item As Outlook.MailItem)
Dim LastName As String
Dim FirstName As String
Dim EncounterDate As String
Dim MRN As String
Dim Body As String

On Error Resume Next

'   Check to make sure it is an Outlook mail message.
    If TypeName(item) <> "MailItem" Then Exit Sub
    Body = item.Body

'   Exract data from the email
    If item.Subject =  _
        gImatchKpEmailSubjectNo Or item.Subject = _ 
        gImatchKpEmailSubjectYes Or _
        item.Subject=_gImatchKpEmailSubjectMaybe Then
           MRN = ExtractText(Body, RegPattern("MRN"))
           LastName = ExtractText(Body, RegPattern("LastName"))
           FirstName = ExtractText(Body, RegPattern("FirstName"))
           EncounterDate = ExtractText(Body, RegPattern("EncounterDate"))
    End If
End Sub

RegPattern 函数如下所示:

Public Function RegPattern(Lookup As String) As String 'Creates a 
  regPattern for each type of lookup

On Error Resume Next

    Select Case Lookup
        Case "LastName"
            RegPattern = "Patient\s*[:]+\s*(\w*)\s*"
        Case "FirstName"
            RegPattern = "Patient\s*[:]+\s*(\w*)[,](\w*)\s*"
        Case "EncounterDate"
            RegPattern = "EncounterDate\s*[:]+\s*(\w*)\s*" 
        Case "MRN"
            RegPattern = "MRN\s*[:]+\s*(\d*)\s*"
    End Select

    Debug.Print Lookup, RegPattern

End Function

ExtractText 函数如下所示:

Public Function ExtractText(Str As String, RegPattern As String) As 
   String
Dim regEx As New RegExp
Dim numMatches As MatchCollection
Dim M As Match

On Error Resume Next

regEx.Pattern = RegPattern

Set numMatches = regEx.Execute(Str)
If numMatches.Count = 0 Then
    ExtractText = "missing"
Else
    Set M = numMatches(0)
    ExtractText = M.SubMatches(0)
End If

Debug.Print ExtractText
End Function

当我运行此程序时,代码会提取新电子邮件,并设法准确提取 MRN (12345678) 和患者姓氏 (Smith)。

但是,它还将患者的名字提取为 (Smith)。同样,它将 Encounter Date 拉为 (Apr),但会丢失其余部分。

谁能告诉我正确的RegEx 代码是什么来获取患者的名字以及整个就诊日期?

感谢您的帮助。

【问题讨论】:

  • Outlook可以运行vbscript代码吗?
  • 但是,一次检查一个正则表达式,这个Patient\s*[:]+\s*(\w*)\s* 只会匹配一组单词。我假设这是姓氏。此外,vbsctipt(或 vba?)是否遵循双引号规则(即必须转义转义)?
  • 好的,看来您应该使用 1 个正则表达式来一次获取姓氏,名字。使用 First 名称并在第 1 组中获取 last,在第 2 组中获取 first。建议:如果没有名字,请不要在正则表达式中需要它。 Patient\s*[:]+(?:\s*(\w+)(?:\s*,\s*(\w+))?)?
  • 注意 - 正则表达式相当普遍,一些非常了解正则表达式的人可能不知道您的语言用法。其他了解您的语言用法的人可能不太了解正则表达式。您可以优先考虑哪个方面最能帮助您的问题。否则,垃圾进,垃圾出。
  • 谢谢你的罪。您建议的代码完全符合我的预期。

标签: regex vba email outlook


【解决方案1】:
"Patient\s*[:]+\s*(\w*)[,](\w*)\s*"

核心问题是你总是提取第 0 个子匹配;但是你有两组捕获括号。将第一组括号更改为非捕获括号应该会有所帮助:

"Patient\s*[:]+\s*(?:\w*)[,](\w*)\s*"

或者甚至没有括号作为名字,因为没有理由需要在那里分组。

另请注意,[:]: 相同,您可能希望为名称捕获至少一个字符,即 \w+ 而不是 \w*

【讨论】:

  • 感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多