re.DOTALL未匹配换行符?正则提取指定命令内容遇困
解决re.DOTALL无法匹配换行符并提取目标内容的问题
让我们一步步拆解并解决你的问题:
问题根源分析
你当前的正则表达式 re.findall(">.*([A-Z 0-9]*).*, reply from", string, re.DOTALL) 存在两个核心问题:
- 贪婪匹配导致捕获失效:
.*是贪婪模式,会从>开始尽可能匹配到最接近, reply from的内容,这会让后面的([A-Z 0-9]*)只能捕获到空或者最后几个符合规则的字符,完全拿不到你想要的完整目标片段。 - 未匹配到实际的转义字符:你的字符串里的右尖括号是HTML转义后的
>,而不是直接的>,所以正则里的>根本匹配不到目标位置。
修正后的正则表达式
针对你的需求,我们可以调整正则为:
import re string = '\n\n <!----><div class="screen-reader-text" ng-if="::(ctrl.messageViewModel.isChat || ctrl.messageViewModel.isReply)" role="heading" aria-level="5">\n\n\nADMIN_COMMAND STOP\n\n, reply from YATIN </div><!---->\n\n <!--Chat head-->\n <div class="media-left" ng-class="{ \'hide-media-left\' : ctrl.messageViewModel.editFormVisible }">\n <!-- Person icon -->\n \n <!---->\n \n </div>\n\n <div class="ts-message-thread-body align-item-left" data-tid="messageThreadBody" ng-class="{\'has-attachments\': ctrl.messageViewModel.hasAttachments} ">\n <!--EditMessage-->\n <!---->\n <!--EditMessage-->\n <!----><div id="messageBody" class="message-body message-body-width" ng-if="!ctrl.messageViewModel.editFormVisible" simple-mouseenter="!ctrl.isInteropChat &amp;&amp; ctrl.messageReactionsEnabled &amp;&amp; ctrl.showMessageActions($event, this)" ng-mouseleave="!ctrl.isInteropChat &amp;&amp; ctrl.messageReactionsEnabled &amp;&amp; ctrl.hoverOutMessageBodyHandler($event)">\n <!----><div class="message-body-top-row padded-content" ng-if="!ctrl.isHiddenByDlp" ng-class="{ \'unread-message\': ctrl.messageViewModel.isNewMessage,\n \'has-reactions\': ctrl.messageReactionsEnabled &amp;&amp; ctrl.messageViewModel.messageHasReaction}">\n <div class="top-row-text-container" ng-class="{\'single-line-truncation\': ctrl.messageReactionsEnabled &amp;&amp; ctrl.messageViewModel.isRightRail}">\n <!--Name-->\n <div class="ts-msg-name app-small-font" data-tid="threadBodyDisplayName" dir="auto">\n and so on...\n' # 修正后的正则 matches = re.findall(r'>.*?\n+([A-Z0-9 ]+)\n+.*?, reply from', string, re.DOTALL) print(matches) # 输出: ['ADMIN_COMMAND STOP']
正则规则详解
>:匹配字符串中实际存在的HTML转义右尖括号,这是之前匹配失败的关键之一。.*?:非贪婪模式的任意字符匹配,确保只匹配到目标内容前的必要部分,不会过度吞噬字符导致捕获组失效。\n+:匹配目标内容前后的多个换行符,精准定位目标片段的位置(符合你提到的目标内容前后可能有多个换行的场景)。([A-Z0-9 ]+):捕获由大写字母、数字和空格组成的目标内容,用+替代*确保至少匹配一个字符,避免捕获空内容。.*?, reply from:非贪婪匹配到, reply from结束,确保不会跳过目标内容。
额外优化建议
如果目标内容的前后不一定是严格的换行符,也可以用\s*匹配任意空白字符(包括换行、空格、制表符等),让正则更灵活:
matches = re.findall(r'>.*?\s*([A-Z0-9 ]+)\s*.*?, reply from', string, re.DOTALL)
这样即使目标内容前后是混合的空格和换行,也能正确捕获。
内容的提问来源于stack exchange,提问作者Sabito
相关产品推荐
相关产品推荐

