.*?的缺陷谁能说说? 在一个超大字符串(没分行数据)里用 5 个左右的 .*? 会出现不可预料的结果

2022-10-10 13:48:16 +08:00
 blackantt

.?的缺陷谁能说说? 在一个超大字符串(没分行数据)里用 5 个左右的 .? 会出现不可预料的结果

按记录分行后,.? 就正常了。 问题是就算对记录预先分行,如果每次都先按记录来分行,再 .? 。 那工作量太大。 如果分错, 那结果也就不对了。

详见, https://fishc.com.cn/thread-219007-1-1.html

2533 次点击
所在节点    Python
8 条回复
wxf666
2022-10-10 14:14:03 +08:00
怎么下载样例文件呢。。还要注册个账号?会不会积分不够,还得灌个水啥的?

除非搜索 /替换需求特别简单,否则正则不适合用于 html xml 这种数据上

推荐 BeautifulSoup lxml 等库,使用里面的 css selector 或 xpath 功能
fbichijing
2022-10-10 16:21:46 +08:00
@wxf666 确实如此。一开始的时候我还喜欢用正则去抓取某些不是很规则的数据,感觉还有那么一丢丢的方便。但随着使用次数的增多,发现直接使用提取器更加简单直接,节省去测试正则的时间。
blackantt
2022-10-10 17:28:09 +08:00
@wxf666 重新上传到一个直接下载的地方了,请看
wxf666
2022-10-10 19:26:01 +08:00
@blackantt 粗试了一下,Python 的正则是没问题的,因为在 regex101.comregexr.com 、Notedpad++ 等,都匹配到了相同的结果

初步认为,你的正则出问题了
liuidetmks
2022-10-10 19:29:44 +08:00
忘记哪看的,文法里面如果嵌套多个模糊匹配,消耗资源指数上升。
wxf666
2022-10-10 21:31:23 +08:00
@liuidetmks 可能你说的是 [灾难性回溯]( https://zh.javascript.info/regexp-catastrophic-backtracking ) ?


@blackantt 实在不想改你的正则了,你自己去 regex101.com ,把你的正则、html 丢进去,看看都匹配了 7 个啥吧

帮你把正则改成这样,然后在左边选择 `ECMAScript (JavaScript)` 引擎,可以看到每个匹配 *(淡蓝色)* 及其各自的 6 个 `(.*?)` *(绿橙紫粉红绿)* 都长啥样:

```regex
<div class="css-em857x"><a title="(.*?) profile" href="\/profile\/\d{6,8}">(.*?)<\/a><\/div><\/h4>(.*?)title="(.*?)"(.*?)<\/span><\/div><div class="MuiBox-root css-15ro776"><span aria-hidden="true" title="China" (.*?)1 shared interest: Languages &amp; Cultures<\/p><\/div><div class=
```


写了段用 lxml 库的 xpath 功能抽取结果的 Python 代码:

*( V 站排版原因,行首加了全角空格,记得删除)*

```python
import lxml

html = lxml.html.parse(r'C:\Users\dengz\Downloads\out8.txt')

for node in html.xpath(
  '//div[@role="listitem" and '
  './/div[@class="MuiBox-root css-k008qs"]/*[2] and '
  './/p[contains(text(), "1 shared interest")]]'):
  n1 = node.xpath('.//a[text()]')[0]
  n2 = node.xpath('.//div[@class="MuiBox-root css-15ro776"][2]/span')[0]
  print([n1.get('href'), n1.text, n2.get('title')])
```
ch2
2022-10-10 21:35:15 +08:00
你需要的是一个语法分析器,别用词法分析工具干这种需求了
pppguest3962
2022-10-14 14:59:43 +08:00
我个人感觉,在 python 里 re 效率要比 bs,lxml 里的 xpath 取值,速度上要麻利得多,
html 的正则匹配从来都不是全文检索的,除非特征很明显并且不变,唯一。
我一般的做法是 A 对象正则匹配全文 html 的可能范围,
B 对象从 A 对象中正则匹配可能段落,
C 对象从 B 对象中正则析出目标值,
这样也比 bs ,lxml.xpath 取值速度要快
而且每一步容错的空间也很大,好操作。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/885774

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX