用于匹配除特定单词之外的字符串的正则表达式
RegEx for matching a string except specific words
在 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
对于第一个字符串,我想要整个字符串 returned 但只有以下是 returned:
CHECKOUT 高级客户服务经理 FRONTENDMGR:07:00 上午 - 08:30 上午
对于第二个字符串,我只需要从 "CHECKOUT" 到 "01:00 PM" returned 的字符串的第一部分,效果很好。
对于第三个字符串,我只想要 "CHECKOUT" 到“01:00 PM”returned 之间的部分。
所以唯一没有出现的是第一个字符串,我想要整个字符串 returned 但只有第一部分匹配。
所以我需要调整模式以包括所有内容,除非 "DRY GOODS" 这个词在字符串中,如果是这样,只有 return 单词 "CHECKOUT" 和 [= 之间的部分30=] 或 "PM".
您可以更新您的模式以在匹配后使用否定前瞻 (?!
来断言右侧的内容不包含 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_(/ ):]+
匹配字符 class 中列出的任意字符 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)
断言右边的内容不包含单词边界之间的 DRY GOODS
.*
匹配任意字符 0+ 次
根据您展示的内容和您的描述,我认为这可以做到:
\bCHECKOUT.*?(?=\s*DRY GOODS|$)
这将 return,来自您的数据:
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|$)
在 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
对于第一个字符串,我想要整个字符串 returned 但只有以下是 returned: CHECKOUT 高级客户服务经理 FRONTENDMGR:07:00 上午 - 08:30 上午
对于第二个字符串,我只需要从 "CHECKOUT" 到 "01:00 PM" returned 的字符串的第一部分,效果很好。
对于第三个字符串,我只想要 "CHECKOUT" 到“01:00 PM”returned 之间的部分。
所以唯一没有出现的是第一个字符串,我想要整个字符串 returned 但只有第一部分匹配。
所以我需要调整模式以包括所有内容,除非 "DRY GOODS" 这个词在字符串中,如果是这样,只有 return 单词 "CHECKOUT" 和 [= 之间的部分30=] 或 "PM".
您可以更新您的模式以在匹配后使用否定前瞻 (?!
来断言右侧的内容不包含 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_(/ ):]+
匹配字符 class 中列出的任意字符 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)
断言右边的内容不包含单词边界之间的 DRY GOODS.*
匹配任意字符 0+ 次
根据您展示的内容和您的描述,我认为这可以做到:
\bCHECKOUT.*?(?=\s*DRY GOODS|$)
这将 return,来自您的数据:
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|$)