推荐学习书目
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
jin6220
V2EX  ›  Python

想了一个多小时,求个{正则}大神看看如何正则出下面 json 里的数据。

  •  
  •   jin6220 · Jan 14, 2017 · 4502 views
    This topic created in 3468 days ago, the information mentioned may be changed or developed.
    每次正则都有从头看一遍,
    想了一个多小时了。
    就把标题给正则出了
    还有标题下下面的网址求问如何弄出来?
    "title_hide": "给你的键盘加上无线 PPT 控制功能吧",
    "date_modified": "2013-05-24T11:23:42.260648+08:00",
    "url": "http://www.guokr.com/article/437046/",
    "title": "给你的键盘加上无线 PPT 控制功能吧",
    "small_image": "http://2.im.guokr.com/BFnIhI2uKOFbTt44KurAN3zMyaJjXmao9OciN4ayjkLgAQAASQEAAEpQ.jpg",
    "summary": "这个项目也是一个很好的焊接技巧入门练习。",
    "ukey_author": "m4tq2j",
    "date_created": "2013-05-24T11:19:42.252645+08:00",
    "resource_url": "http://apis.guokr.com/minisite/article/437046.json"
    上面代码是 json 一角,需要的部分是 title_hide ,这个已解出,另一个部分是下下行的 url.


    这是我写的代码:

    import requests
    import re
    import json
    from bs4 import BeautifulSoup
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'}
    def gker(url):
    html=requests.get(url, headers=headers).text
    return html

    j=gker('http://www.guokr.com/apis/minisite/article.jsonretrieve_type=by_subject&subject_key=diy&limit=20&offset=18&_=1484373021355')
    j2=str(json.loads(j)) #必须转换成字符串才能正则匹配。

    titles=re.findall(r"(?<='title_hide':).*?(?=,)",j2,re.M)
    print(len(titles))
    for title in titles:
    print(title)

    urls=re.findall(r"'url':(.*?),.?'title'",j2,re.M) #这里不对,不知道如何弄出来了
    print(len(urls),urls)
    38 replies    2017-01-16 08:55:39 +08:00
    jin6220
        1
    jin6220  
    OP
       Jan 14, 2017
    for title in titles:
    print(title)
    别人上传的代码怎么那么结构清晰啊 =,=
    zhjits
        2
    zhjits  
       Jan 14, 2017
    直接读 JSON 转成的 dict 不行么
    decken
        3
    decken  
       Jan 14, 2017 via iPhone
    用 json.loads 反序列化出对象,再 get 一下就 ok 了
    golmic
        4
    golmic  
       Jan 14, 2017 via Android
    url":"[^"]+
    privil
        5
    privil  
       Jan 14, 2017 via iPhone
    @jin6220 别人用 md 格式了呗,楼上正解, json 搞出来的事 dict ,打印字典指定值被
    cdwyd
        6
    cdwyd  
       Jan 14, 2017 via Android
    re.compile('article/(\d+)/')
    fy
        7
    fy  
       Jan 14, 2017
    这需求不要用正则,本身例外多早晚出事。直接 json 解轻松愉快。
    jin6220
        8
    jin6220  
    OP
       Jan 14, 2017
    @zhjits 是已经转换成 dict 了 但是现在正则已经弄出一半数据了 。。。
    Yinz
        9
    Yinz  
       Jan 14, 2017
    如果不要求一定用正则的话, json 直接读成 dict 就好了,如 3 、 5 楼所说

    j2=str(json.loads(j)) #必须转换成字符串才能正则匹配。

    titles=re.findall(r"(?<='title_hide':).*?(?=,)",j2,re.M)
    print(len(titles))
    for title in titles:
    print(title)

    urls=re.findall(r"'url':(.*?),.?'title'",j2,re.M) #这里不对,不知道如何弄出来了
    print(len(urls),urls)

    上面这几行改成
    j2=json.loads(j)
    print(j2.get('title_hide'))
    print(j2.get('url'))

    应该就没问题的了
    Yinz
        10
    Yinz  
       Jan 14, 2017
    @jin6220 沉没成本不要算啊,毕竟转 dict 之后简单太多了
    jin6220
        11
    jin6220  
    OP
       Jan 14, 2017
    当初没用字典是嫌麻烦,各种套嵌。看来明天还得再看看正则。
    jin6220
        12
    jin6220  
    OP
       Jan 14, 2017
    ======自答下:=========
    第一步: a=j2['result'] (这里 j2 就不用字符串话了)
    第二部:
    >>> for b in a :
    print(b.get('title_hide'))


    制作一个万花筒,来一场镜花水月的邂逅
    让翅膀在指尖上舞动:用铁丝制作在指尖扇动的小机械
    来做一个漂亮的鱼标本吧!
    低成本打造头戴式立体声蓝牙耳机
    自动温调速风扇,让你的电脑更冷静
    给你的键盘加上无线 PPT 控制功能吧
    给钛挂件镀一层彩色外衣
    泥塑入门,做个蒸汽朋克范儿黄金头骨
    送妹纸魔方拼图,你也可以
    温差发电机:不用电的“智能”风扇
    手机?投影机?一个盒子就可兼得!
    GEEK 小浪漫:靠在一起就会闪烁的心
    制作属于你自己的球形关节人偶
    GEEK 厨房之草莓酱,和一坨肉眼可见 DNA
    沏一壶苔藓
    软木塞变身灰袍甘道夫
    自制模具,巧克力形状随便你
    情人节,送 Ta 一支彩虹玫瑰!
    远程电子点火器,安全烟火必备
    化学小实验:居家版“法老之蛇”
    >>> for b in a :
    print(b.get('url'))


    http://www.guokr.com/article/437636/
    http://www.guokr.com/article/437297/
    http://www.guokr.com/article/437489/
    http://www.guokr.com/article/437145/
    http://www.guokr.com/article/437064/
    http://www.guokr.com/article/437046/
    http://www.guokr.com/article/437010/
    http://www.guokr.com/article/436762/
    http://www.guokr.com/article/436941/
    http://www.guokr.com/article/436937/
    http://www.guokr.com/article/436912/
    http://www.guokr.com/article/436915/
    http://www.guokr.com/article/436835/
    http://www.guokr.com/article/436799/
    http://www.guokr.com/article/436722/
    http://www.guokr.com/article/436694/
    http://www.guokr.com/article/436679/
    http://www.guokr.com/article/436667/
    http://www.guokr.com/article/436640/
    http://www.guokr.com/article/436644/
    >>>
    jin6220
        13
    jin6220  
    OP
       Jan 14, 2017
    @Yinz 嗯 你那个结构好像不对 但是换成 json 无非就是套嵌 dict 循环下就立马解出了 正则不如派森像是人类语言啊啊啊
    但是还是很想弄懂正则怎么写 毕竟有时候只有正则解决问题很暴力 =,=
    lxy
        14
    lxy  
       Jan 15, 2017
    要是有人在工作中有 json 不用非要用正则写一堆“乱码”会被我捏脸的。 4 楼那个就是了,不过漏了空格,稍微严谨一点的写法:
    "url"\s*:\s*"(.+?)"\s*,
    Allianzcortex
        15
    Allianzcortex  
       Jan 15, 2017
    其实我想说的很多时候返回的 JSON 格式顺序是不固定的,调好了这一个正则,下次请求的时候内容就又变了。所以???
    Yinz
        16
    Yinz  
       Jan 15, 2017
    @jin6220 这。。。别循环啊,自己分析下 json 的格式然后逐步 get 就好了,没必要循环找元素吧
    jin6220
        17
    jin6220  
    OP
       Jan 15, 2017
    @Yinz 里头的主体结构类似是:
    { "result": [{"title_hide": ...,,"url": ...},{title_hide:...,url:...},{title_hide:...,url:...},,{title_hide:...,url:...},其他字典]}
    result 的值是一个列表,列表里的字典都是并列结构,不循环可以?
    jin6220
        18
    jin6220  
    OP
       Jan 15, 2017
    wyntergreg
        19
    wyntergreg  
       Jan 15, 2017
    不用 JSON 非要正则,舍近求远?
    allenhu
        20
    allenhu  
       Jan 15, 2017 via Android
    无知者无畏
    jin6220
        21
    jin6220  
    OP
       Jan 15, 2017
    @allenhu 我是新手,不过也不从事程序猿专业,接触的数据应该都会很简单。
    jin6220
        22
    jin6220  
    OP
       Jan 15, 2017
    正则前后关系匹配:"url"\s*:\s*"(.+?)"\,\s*"title re.M
    但是实际 url 的邻居可能会变.
    jin6220
        23
    jin6220  
    OP
       Jan 15, 2017
    吃饭去了。。。
    总结下
    非正则的办法:
    第一步: a=j2['result'] (这里 j2 就不用字符串话了)
    a 是一个列表,里面是 20 个并联关系的字典。
    第二部:
    >>> for b in a :
    print(b.get('title_hide'))
    >>> for b in a :
    print(b.get('url'))

    正则方法:
    第一种
    urls=re.findall(r"(?<='url':)\s*'http://www.guokr.com/article/\d{5,7}/'(?=,)",str(j2))
    第二种(看运气,前后邻居可能会变,然后就失效)
    urlsre=re.findall(r"'url'\s*:\s*'(.+?)',\s*'title'",str(j2),re.M)
    Valyrian
        24
    Valyrian  
       Jan 15, 2017 via iPad   ❤️ 1
    这是理论上行不通的,因为 regex parse 的是 regular language , json isn't a regular language
    http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags
    aheadlead
        25
    aheadlead  
       Jan 15, 2017 via iPad
    @lxy 捏脸好评
    jin6220
        26
    jin6220  
    OP
       Jan 15, 2017
    @Valyrian 理论是不行,第一次也是发现不对,然后就把 json ( dict )数据 str 化了,最后是找到结果了。
    sola97
        27
    sola97  
       Jan 15, 2017 via Android
    这么简单还不用 dict...有写正则的功夫早就 get 完了
    Merlini
        28
    Merlini  
       Jan 15, 2017 via Android
    而且正则也慢啊
    zzn
        29
    zzn  
       Jan 15, 2017   ❤️ 1
    解析 xml/json 不要用正则
    解析 xml/json 不要用正则
    解析 xml/json 不要用正则
    zhidian
        30
    zhidian  
       Jan 15, 2017
    JSON 也有 xpath 类似的工具啊……
    jin6220
        31
    jin6220  
    OP
       Jan 15, 2017
    @zzn 那用什么啊 对这块不太懂 这个 json 没显示汉字,变成字典显示之后然后正则的
    imlonghao
        32
    imlonghao  
       Jan 15, 2017
    import requests

    a = requests.get('http://www.guokr.com/apis/minisite/article.json?retrieve_type=by_subject&subject_key=diy&limit=20&offset=18&_=1484373021355').json()

    result = [[x['title_hide'], x['url']] for x in a['result']]
    imlonghao
        33
    imlonghao  
       Jan 15, 2017
    不!要!用!正!则!处!理 json 数!据!
    jin6220
        34
    jin6220  
    OP
       Jan 15, 2017
    @imlonghao 嗯 这个列表表达式用的好 学习了 比 for 循环简洁,但是没 for 循环好理解。
    eoo
        35
    eoo  
       Jan 15, 2017 via Android
    PHP json_decode($json); 搞定 啊哈哈
    Ouyangan
        36
    Ouyangan  
       Jan 16, 2017
    正则处理 json 属于野路子.本身就是结构化的数据为什么用正则呢?
    xiamx
        37
    xiamx  
       Jan 16, 2017
    @jin6220 楼主看看 @Valyrian 给的链接。 JSON 是 Context-free grammar ,不是 regular language 所以不能用正则解析(当然,某些子集还是属于 regular language 的)
    jin6220
        38
    jin6220  
    OP
       Jan 16, 2017
    @xiamx 好吧 谢谢,有个疑问,那个网站的 json 数据转换为字典之后(因为里头的汉字没显示出来。),然后 str 字符串化,这样正则可以吗?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1060 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 71ms · UTC 18:31 · PVG 02:31 · LAX 11:31 · JFK 14:31
    ♥ Do have faith in what you're doing.