【问题标题】:RegEx for matching a string except specific words用于匹配除特定单词之外的字符串的正则表达式
【发布时间】:2019-05-23 15:23:47
【问题描述】:

在 Excel VBA 中,我尝试使用正则表达式方法来匹配字符串。一旦匹配发生,我希望匹配的字符串包含整个字符串,除非在匹配字符串结束后出现关键字。换个说法,正则表达式模式如下:

pattern = (CHECKOUT[a-zA-Z_(/ ):]+\w+:\w+\s((AM|PM)|(am|pm))\s\-\s\w+:\w+\s((AM|PM)|(am|pm)))

输入的字符串是:

1. CHECKOUT Senior Guest Services Manager FRONTENDMGR: 07:00 AM - 08:30 AM SGSM_BOOKKEEPING: 08:30 AM - 01:00 PM FRONTENDMGR: 01:00 PM - 04:00 PM

2. CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM DRY GOODS Receiving Clerk RECEIVE: 04:30 AM - 09:00 AM 

3. DRY GOODS Receiving Clerk RECEIVE: 04:30 AM - 09:00 AM CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM

对于第一个字符串,我希望返回整个字符串,但只返回以下内容: 退房高级宾客服务经理 FRONTENDMGR:07:00 AM - 08:30 AM

对于第二个字符串,我只希望返回从“CHECKOUT”到“01:00 PM”的字符串的第一部分,并且效果很好。

对于第三个字符串,我只希望返回“CHECKOUT”到“01:00 PM”之间的部分并发生这种情况。

所以唯一没有出现的是第一个字符串,我希望返回整个字符串,但只有第一部分匹配。

所以我需要调整模式以包含所有内容,除非字符串中包含“DRY GOODS”一词,如果是,则仅返回“CHECKOUT”和“AM”或“PM”之间的部分。

【问题讨论】:

    标签: regex excel vba regex-negation regex-lookarounds


    【解决方案1】:

    从你的展示和描述来看,我认为这可能会做到:

    \bCHECKOUT.*?(?=\s*DRY GOODS|$)
    

    这将从您的数据中返回:

    CHECKOUT Senior Guest Services Manager FRONTENDMGR: 07:00 AM - 08:30 AM SGSM_BOOKKEEPING: 08:30 AM - 01:00 PM FRONTENDMGR: 01:00 PM - 04:00 PM
    CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM
    CHECKOUT Guest Services Manager BOOKKEEPER: 09:00 AM - 01:00 PM
    

    我们匹配CHECKOUT,然后匹配其他所有内容(但不包括)DRY GOODS。如果我们没有找到DRY GOODS,我们继续到字符串的末尾。

    如果字符串超过多行,可能需要将.*? 替换为[\s\S]*?

    如果您的数据绝对必须匹配最后的AM|PM,请尝试:

    \bCHECKOUT.*(?:AM|PM)(?=.*?DRY GOODS|$)
    

    【讨论】:

      【解决方案2】:

      您可能会更新您的模式以在匹配后使用否定前瞻 (?! 来断言右侧的内容不包含 DRY GOOD

      \bCHECKOUT[a-zA-Z_(/ ):]+\w+:\w+\s(?:[AP]M|[ap]m)\s-\s\w+:\w+\s(?:[AP]M|[ap]m)(?!.*\bDRY GOODS\b).*
      

      说明

      • \bCHECKOUT 逐字匹配单词边界,以防止单词成为更大单词的一部分
      • [a-zA-Z_(/ ):]+ 匹配字符类中列出的任何字符的 1 次以上
      • \w+:\w+\s 匹配 1+ 个单词字符,然后是 :,再匹配 1+ 个单词字符,然后是空格字符
      • (?:[AP]M|[ap]m) 匹配 AM PM am pm
      • \s-\s\w+:\w+\s 匹配一系列空白字符、-: 和单词字符
      • (?:[AP]M|[ap]m) 匹配 AM PM am pm
      • (?!.*\bDRY GOODS\b) 断言右边的内容不包含单词边界之间的干货
      • .* 匹配任意字符 0+ 次

      Regex demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多