【问题标题】:Url parsing with regex使用正则表达式解析网址
【发布时间】:2014-08-12 13:56:05
【问题描述】:

我有几个网址。我想解析一个特定的数字,这样我就可以把它保存到一个变量中,比如:

if number ==15 : 
    category ='tree'
elif number ==20:
    category ='flower'
elif number ==3:
    category ='bird'

网址的格式为:

http://www.test.tw/in/15   
http://www.test.tw/in/15?page=2  
http://www.test.tw/in/15/#/?page=3
http://www.test.tw/in/20/#/?page=2
http://www.test.tw/in/3/?page=5

到目前为止,我正在使用的方法:

urls = (
    ('http://www.test.tw/in/15','tree'),    #category =x[1]
    ('http://www.test.tw/in/20','flower'),   
    ('http://www.test.tw/in/3','bird'),   
)

但是当 url 有类似 ?page=2 的内容时,它就不起作用了。

【问题讨论】:

  • 你想要那个正则表达式吗?
  • 我觉得可以。只要让我保存到变量:category

标签: python regex url


【解决方案1】:

你不需要使用正则表达式。

使用urlparse.urlparse(Python 3.x 中为urllib.parse.urlparse):

>>> import urlparse
>>> urlparse.urlparse('http://www.test.tw/in/15/#/?page=3')
ParseResult(scheme='http', netloc='www.test.tw', path='/in/15/', params='', query='', fragment='/?page=3')
>>> urlparse.urlparse('http://www.test.tw/in/15/#/?page=3').path.rstrip('/').rsplit('/')[-1]
'15'

【讨论】:

    【解决方案2】:

    您可以使用正则表达式来搜索您的模式,然后使用字典而不是 if-else 链:

    import re
    
    pattern = re.compile(r'/in/(\d+)')
    categories = {'15': 'tree', '20': 'flower', '3': 'bird'}
    
    def getcategory(url):
        category = pattern.search(url).group(1)
        return categories[category]
    

    示例

    urls = ['http://www.test.tw/in/15',
            'http://www.test.tw/in/15?page=2',
            'http://www.test.tw/in/15/#/?page=3',
            'http://www.test.tw/in/20/#/?page=2',
            'http://www.test.tw/in/3/?page=5']
    
    print [(url, getcategory(url)) for url in urls]
    

    输出

    [('http://www.test.tw/in/15', 'tree'),
     ('http://www.test.tw/in/15?page=2', 'tree'),
     ('http://www.test.tw/in/15/#/?page=3', 'tree'),
     ('http://www.test.tw/in/20/#/?page=2', 'flower'),
     ('http://www.test.tw/in/3/?page=5', 'bird')]
    

    【讨论】:

      【解决方案3】:

      按照其他人的建议使用urlparse,并将正则表达式作为最后的手段。

      (?<=\/)\d+(?=\/|\?|$)
      

      这里是online demo

      示例代码:

      import re
      p = re.compile(ur'(?<=\/)\d+(?=\/|\?|$)', re.MULTILINE)
      test_str = u"URLs"
      
      re.findall(p, test_str)
      

      【讨论】:

        【解决方案4】:

        您也可以使用正则表达式,但仍然需要 urlparse。 将两者结合起来,您可以这样做:

        import urlparse
        import re
        my_url = urlparse.urlparse('http://www.test.tw/in/15/#/?page=3')
        my_match = re.match(r"/in/(?P<num>\d+)/$", my_url.path)
        my_match.group("num")
        >> 15
        

        但是您确实可以看到,这很脆弱,并且依赖于所有 url 看起来“相同”,但它适用于 Django :)

        【讨论】:

          【解决方案5】:

          对于基于正则表达式的方法:

          import re
          list = ["http://www.test.tw/in/15", "http://www.test.tw/in/15?page=2",
                  "http://www.test.tw/in/15/#/?page=3",
                  "http://www.test.tw/in/20/#/?page=2", "http://www.test.tw/in/3/?page=5"]
          urls = ()
          categories = {"tree": [], "flower": [], "bird": []}
          for i in list:
              category = int(re.search("(http\:\/\/.+)\/(\d+)", i).group(2))
          
              if category == 15:
                  urls += ((i, "tree"),)
              elif category == 20:
                  urls += ((i, "flower"),)
              elif category == 3:
                  urls += ((i, "bird"),)
          
          print urls
          

          输出

          (('http://www.test.tw/in/15', 'tree'), ('http://www.test.tw/in/15?page=2', 'tree'), ('http://www.test.tw/in/15/#/?page=3', 'tree'), ('http://www.test.tw/in/20/#/?page=2', 'flower'), ('http://www.test.tw/in/3/?page=5', 'bird'))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多