Python:使用正则表达式或其他方式提取网址

时间:2018-09-02 15:16:17

标签: python regex pandas

我为一个问题感到困惑。我有一个很大的数据框,其中的两列是这样的:

pd.DataFrame([['a', 'https://gofundme.com/ydvmve-surgery-for-jax,https://twitter.com/dog_rates/status/890971913173991426/photo/1'],          ['b','https://twitter.com/dog_rates/status/890971913173991426/photo/1,https://twitter.com/dog_rates/status/890971913173991426/photo/1'],['c','https://twitter.com/dog_rates/status/890971913173991430/video/1'] ],columns=['ID','URLs'])

我想做的是仅保留每个单元格中包含“ twitter”一词的网址,并删除其余的网址。模式是我想要的URL始终包含单词“ twitter”,并以“ /” +一个数字结尾。如果在同一单元格中有两个相同的URL,则仅应保留一个。像这样:

Test2 = pd.DataFrame([['a', 'https://twitter.com/dog_rates/status/890971913173991426/photo/1'],
 ['b','https://twitter.com/dog_rates/status/890971913173991426/photo/1'],
 ['c','https://twitter.com/dog_rates/status/890971913173991430/video/1'] ],columns=['ID','URLs'])

Test2

我是Python的新手,经过大量的搜索之后,我开始理解叫做regex的东西就是答案,但这是我的认识。在Stackoverflow上的一篇帖子中,我进入了regex101.com,经过反复试验,据我所知,它不起作用:

r’^[https]+(:)(//)(.*?)(/)(\d)’

谁能告诉我如何解决这个问题? 预先感谢。

1 个答案:

答案 0 :(得分:3)

正则表达式对于此类任务当然很方便。请参阅this question和在线工具,例如regex101,以了解更多信息。

您当前的模式不正确,因为:

  • ^在字符串的开头匹配以下模式。
  • [https]+这是一个字符集,表示它将与hsps匹配,因此{{1 }}方括号,而不仅仅是您要使用的字符串[]http
  • https您无需将此(:)放在此处的捕获组中。
  • : (//)需要在正则表达式/中转义。这里也不需要捕获群组。
  • \/当可以使用否定字符集(.*?)时,常常会误用.*?组合。
  • [^]如上所述。
  • (/)匹配并捕获一个数字。此处的捕获组对于您的任务也是多余的。

您可以使用以下表达式:

(\d)
  • https?:\/\/twitter\.com[^,]+(?<=\/\d$) 匹配文字子串https?http
  • https匹配文字子串:\/\/twitter\.com
  • ://twitter.com不是逗号的任何内容,一个或多个。
  • [^,]+令人向往。断言在字符串(?<=\/\d$)的末尾出现/,后跟数字\d

正则表达式演示here


Python演示

$

打印:

import pandas as pd

df = pd.DataFrame([['a', 'https://gofundme.com/ydvmve-surgery-for-jax,https://twitter.com/dog_rates/status/890971913173991426/photo/1'],
                   ['b','https://twitter.com/dog_rates/status/890971913173991426/photo/1,https://twitter.com/dog_rates/status/890971913173991426/photo/1'],
                   ['c','https://twitter.com/dog_rates/status/890971913173991430/video/1'] ],columns=['ID','URLs'])

df['URLs'] = df['URLs'].str.findall(r"https?:\/\/twitter\.com[^,]+(?<=\/\d$)").str[0]
print(df)