如何正则表达式拆分,但保持拆分字符串?

时间:2015-05-31 20:39:27

标签: python regex

我有以下网址格式:

http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/en

我希望在/watch/\d+/之前完成所有工作。

到目前为止,我有:

>>> re.split(r'watch/\d+/', 'http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/en')
['http://www.hulu.jp/', 'supernatural-dub-hollywood-babylon/en']

但是这不包括拆分字符串(域和路径之间出现的字符串)。我想要达到的最终答案是:

http://www.hulu.jp/watch/589851

4 个答案:

答案 0 :(得分:6)

您需要使用捕获组:

>>> re.split(r'(watch/\d+/)', 'http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/en')
['http://www.hulu.jp/', 'watch/589851/', 'supernatural-dub-hollywood-babylon/en']

答案 1 :(得分:4)

如其他答案中所述,您需要使用组来捕获拆分字符串之间的“粘合剂”。

我想知道,你想要的是split()还是search()?它(从示例中)查看您尝试从URL中提取从第一次出现的/watch/XXX/ XXX是1位或更多位数到字符串末尾的所有内容。如果是这种情况,那么匹配/搜索可能更合适,如果搜索正则表达式可以匹配多次,则分割为多个组。例如:

re.split(r'(watch/\d+/)', 'http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf')
['http://www.hulu.jp/', 'watch/589851/', 'supernatural-dub-hollywood-babylon/', 'watch/2342/', 'fdsaafsdf']

哪个看起来不像你想要的。或许可能:

result = re.search(r'(watch/\d+/)(.*)', 'http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf')
result.groups() if result else []

给出:

('watch/589851/', 'supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf')

你也可以使用这种方法与named groups相结合来获得额外的幻想:

result = re.search(r'(?P<watchId>watch/\d+/)(?P<path>.*)', 'http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf')
result.groupdict() if result else {}

,并提供:

{'path': 'supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf', 'watchId': 'watch/589851/'}

如果您设置了split()方法,您还可以设置maxsplit参数以确保它只拆分一次:

re.split(r'(watch/\d+/)', 'http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf', maxsplit=1)

,并提供:

['http://www.hulu.jp/', 'watch/589851/', 'supernatural-dub-hollywood-babylon/watch/2342/fdsaafsdf']

就个人而言,我发现当将URL解析为组成部分时,具有命名组方法的search()非常有效,因为它允许您在正则表达式本身中命名各个部分,并通过groupdict()获取一个很好的词典,你可以用来处理这些部分。

答案 2 :(得分:0)

你肯定见过the Stack Overflow don't-parse-HTML-with-regex post,是吗?

  

您无法使用正则表达式解析[X] HTML。因为HTML不能被正则表达式解析。正则表达式不是可用于正确解析HTML的工具。正如我之前在HTML-and-regex问题中回答过很多次,正则表达式的使用将不允许您使用HTML。

好吧,正则表达式可以解析网址,但是当有大量更好的工具时,尝试这样做是愚蠢的。

这就是URL的正则表达式:

^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$(+无壳标志)

这只是一堆乱七八糟的角色,对吧? 完全<!/ em>的

不要使用正则表达式解析网址... 差不多。

有一件简单的事情:

  

路径相对URL必须是零个或多个路径段,彼此之间用&#34; /&#34;。

拆分网址应该像url.split("/")一样简单。

from urllib.parse import urlparse, urlunparse

myurl = "http://www.hulu.jp/watch/589851/supernatural-dub-hollywood-babylon/en"

# Run a parser over it
parts = urlparse(myurl)

# Crop the path to UP TO length 2
new_path = str("/".join(parts.path.split("/")[:3]))

# Unparse
urlunparse(parts._replace(path=new_path))
#>>> 'http://www.hulu.jp/watch/589851'

答案 3 :(得分:-1)

您可以尝试使用正则表达式

.*\/watch\/\d+

Working Demo