python - re.DOTALL 没有选择换行符
问题描述
这是我正在使用的字符串:
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 && ctrl.messageReactionsEnabled && ctrl.showMessageActions($event, this)" ng-mouseleave="!ctrl.isInteropChat && ctrl.messageReactionsEnabled && 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 && ctrl.messageViewModel.messageHasReaction}">\n <div class="top-row-text-container" ng-class="{\'single-line-truncation\': ctrl.messageReactionsEnabled && ctrl.messageViewModel.isRightRail}">\n <!--Name-->\n <div class="ts-msg-name app-small-font" data-tid="threadBodyDisplayName" dir="auto">\n
等等...
主要感兴趣的部分是:(>\n\n\nADMIN_COMMAND STOP\n\n, reply from
在),我想从中得到ADMIN_COMMAND STOP
该ADMIN_COMMAND STOP
部分可以是任意长度并且可以有数字。此外,\n
它之前和之后可以有几个 s。
其他输入可以有:
>\n\n\nADMIN_COMMAND REFRESH\n\n, reply from
>0, reply from
>\n\n\n\nADMIN_COMMAND STOP\n\n\n, reply from
我想得到的输出:
ADMIN_COMMAND STOP
ADMIN_COMMAND REFRESH
0
我想出了这个:
re.findall(">.*([A-Z 0-9]*).*, reply from",string,re.DOTALL)
我的逻辑:
然后检查一个
>
,零个或多个任何字符(包括\n
)然后,找到零个或多个大写字母/数字,然后再次检查零个或多个任何字符(包括\n
)
解决方案
它确实找到了匹配项,因为它不返回空列表:
>>> import re
>>> string = ">\n\n\n\nADMIN_COMMAND STOP\n\n\n, reply from"
>>> re.findall(">.*([A-Z 0-9]*).*, reply from",string,re.DOTALL)
['']
问题是捕获组([A-Z 0-9]*)
匹配零个字符,因为所有字符都已经被.*
它之前的贪婪消耗掉了。
[^A-Z 0-9]
您可以通过在捕获组之前使用否定字符类来修复它。现在它不再匹配任何东西,因为_
inADMIN_COMMAND
不在字符类中。修复后,它按预期工作:
>>> re.findall(">[^A-Z 0-9_]*([A-Z 0-9_]*).*, reply from",string,re.DOTALL)
['ADMIN_COMMAND STOP']
请注意,在这种情况下,非贪婪匹配 ,.*?
似乎没有达到预期的效果。即使我们.*?
在捕获组之前和之后都放置,所有字符最终都会被最终匹配,.*?
尽管*
中间有贪婪:
>>> re.findall(">.*?([A-Z 0-9_]*).*?, reply from",string,re.DOTALL)
['']
我不太明白为什么。
推荐阅读
- docker - 在 cpanel 上运行 docker 容器
- html - Angular 6 Datatable在外部过滤后刷新表中的数据
- xamarin.forms - Xamarin Formns:在列表视图中的数据之后创建多个空行
- angular - 查看源页面不使用角度通用 ssr 更新
- excel - 公式通过从输入框中选择返回循环内的#NAME
- python-3.x - 在python3中的字典内编辑列表中的字符串
- javascript - 未捕获的 ReferenceError:$ 未在 Power BI Embedded 中定义
- html - Jquery Chosen 隐藏空的 optgroup
- node.js - 用户帐户的数据库设计
- godot - Godot 文本编辑节点不换行