请教正则匹配问题,同样的正则, BS4 中无法匹配, re 有效。

2016-07-23 00:05:54 +08:00
 a412739861

原以为 BS 带正则很王道,但是今天边走神边写码,就是没有办法写出匹配如下标签的正则,感觉应该是我哪里写错了。我把两边的代码复制过,但是没有用。

匹配了以后是想要标签的内容,而不是这个标签,所以还是用 BS4 比较合适。所以比较不好绕过,而且这里绕过了,以后还得碰上,索性就想问个明白。

字很多,其实重点就是两串代码为什么 BS4 无法匹配,正则可以匹配。我的猜测什么的都可以不用管……

想要搜索的标签示例:

<td class="bgwhite t-汉字"> 1</td>

标示汉字的位置,会是随机的一个汉字。

BS4 的正则:

        soup.find_all('td', class_=re.compile(r'bgwhite\st-(\w+)+')):

搜索出来为空。


re 模块正则:

        result = re.findall(re.compile(r'bgwhite\st-(\w+)+'), str(soup))

能够正确的打出字来。


个人的一些实践:

  1. 只去掉 BS4 中的 td 标签,仍然为空。
  2. re.compile(r'bgwhite\st-(\w+)+')改为 re.compile(r'bgwhite'),能够搜索出,但是因为有其他标签混杂在一起,所以不合适。
  1. re.compile(r'bgwhite.)不行,这里应该是因为没写个数,随便改一下 re.compile(r'bgwhite.{0,100}'),也就和 2 的情况一样了。但是一旦{0 , 100}改为{1 , 100}就又搜不到了。
  2. re.compile(r'bgwhite.?')可行,和 2 的情况一样,全部混在一起了。实际上就跟没有这个正则一样

猜测:

  1. BS4 里的正则大概什么不一样的吗?尤其是对空格的处理。我了解了下,只是说是 match 模式,从开头字符串开始匹配。
  2. class 属性无法支持带元字符的正则? text , href 我都有使用过带元字符的正则,可行,但是 class_属性不支持?(感觉不太可能难)
  3. 我写错了关于空格的正则,但是为什么 RE 模块可以……
3465 次点击
所在节点    Python
9 条回复
fzinfz
2016-07-23 01:00:56 +08:00
空格会把 class 分割成 list
soup.td['class'] == ['bgwhite', 't-汉字']
adv007
2016-07-23 07:49:20 +08:00
\w 匹配不出汉字
aristotll
2016-07-23 08:10:58 +08:00
r#1 @fzinfz bs4 的处理明显是对的 本来就是多个类
a412739861
2016-07-23 09:59:25 +08:00
@fzinfz 这个的确没注意,但是搜索的时候,他会出现,只要满足其中一个,他就会显示出来。
如果是要完全匹配,还是需要**bgwhite t-汉字**去搜,

@adv007 可是正则可以匹配,我在其他地方属性里搜索时,用了\w 是可以匹配出汉字的。\w 匹配字母或数字或下划线或汉字。难道我看的资料有误?
@aristotll 嗯嗯,所以我也不找不出什么问题来……
practicer
2016-07-23 12:40:40 +08:00
只匹配汉字的话:
soup.find_all('td', class_=re.compile(ur'bgwhite\st-[\u4e00-\u9fff]+'))
在 Unicode 编码中只匹配汉字。 4E00-9FFF 为中文字符编码区
a412739861
2016-07-23 14:13:26 +08:00
@practicer python2?
这个实际范围比\w 小,大范围的不行,小范围的也不行吧。
实测也是不行。
practicer
2016-07-23 16:33:54 +08:00
@a412739861 我的 py2.7 windows 环境下可行
a412739861
2016-07-24 11:14:20 +08:00
@practicer
怎么测……找到一个类似情况的网页,然后用 BS4 去 find_all 里面找么……
a412739861
2016-07-31 19:58:11 +08:00
已解决。
@aristotll BS4 对多值的判断好像是只要满足其中一个就会可以,所以搜索还是不太好用。如果这个多值属性是唯一,可以直接拼写,但是如果要在这个里面放正则,好像就立刻不行了。

@adv007 \w 能匹配汉字

@practicer 你测试的是正则而不是多值属性标签吧,正则本身就是可以的

---

我的理解是,如果你用了空格,恐怕就很难搜到一个符合的标签。

解决思路在这。
http://stackoverflow.com/questions/12552211/multiple-values-for-class-attribute
用一个 lambda 匿名函数,对 tag 进行多值属性的判断,在这里可以对每个多值属性进行单独的判断,是否符合正则。

也许还有更简单的解决办法吧……不过直接多值属性放正则似乎是不行的。
python3 , bs4.4 。

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

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

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

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

© 2021 V2EX