V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
a412739861
V2EX  ›  Python

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

  •  
  •   a412739861 · 2016-07-23 00:05:54 +08:00 · 3531 次点击
    这是一个创建于 3050 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原以为 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'),能够搜索出,但是因为有其他标签混杂在一起,所以不合适。
    • 而且这个我不用正则的直接 class_=xxx 的效果一样。
    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 模块可以……
    9 条回复    2016-07-31 19:58:11 +08:00
    fzinfz
        1
    fzinfz  
       2016-07-23 01:00:56 +08:00   ❤️ 1
    空格会把 class 分割成 list
    soup.td['class'] == ['bgwhite', 't-汉字']
    adv007
        2
    adv007  
       2016-07-23 07:49:20 +08:00 via iPhone   ❤️ 1
    \w 匹配不出汉字
    aristotll
        3
    aristotll  
       2016-07-23 08:10:58 +08:00   ❤️ 1
    r#1 @fzinfz bs4 的处理明显是对的 本来就是多个类
    a412739861
        4
    a412739861  
    OP
       2016-07-23 09:59:25 +08:00
    @fzinfz 这个的确没注意,但是搜索的时候,他会出现,只要满足其中一个,他就会显示出来。
    如果是要完全匹配,还是需要**bgwhite t-汉字**去搜,

    @adv007 可是正则可以匹配,我在其他地方属性里搜索时,用了\w 是可以匹配出汉字的。\w 匹配字母或数字或下划线或汉字。难道我看的资料有误?
    @aristotll 嗯嗯,所以我也不找不出什么问题来……
    practicer
        5
    practicer  
       2016-07-23 12:40:40 +08:00   ❤️ 1
    只匹配汉字的话:
    soup.find_all('td', class_=re.compile(ur'bgwhite\st-[\u4e00-\u9fff]+'))
    在 Unicode 编码中只匹配汉字。 4E00-9FFF 为中文字符编码区
    a412739861
        6
    a412739861  
    OP
       2016-07-23 14:13:26 +08:00
    @practicer python2?
    这个实际范围比\w 小,大范围的不行,小范围的也不行吧。
    实测也是不行。
    practicer
        7
    practicer  
       2016-07-23 16:33:54 +08:00
    @a412739861 我的 py2.7 windows 环境下可行
    a412739861
        8
    a412739861  
    OP
       2016-07-24 11:14:20 +08:00
    @practicer
    怎么测……找到一个类似情况的网页,然后用 BS4 去 find_all 里面找么……
    a412739861
        9
    a412739861  
    OP
       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 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5760 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 03:32 · PVG 11:32 · LAX 19:32 · JFK 22:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.