使用Python正则表达式忽略字符串中的`:`

时间:2018-09-21 04:49:16

标签: python regex

我是regex.领域的新手,因此,如果听起来很简单,我感到抱歉。我已经读完regex社区和Lopez的有关精通Python的正则表达式的书,以确保我不会发布初学者级的问题。

我已经从Wiki上抓取了数据(用于学习),并且正在尝试提取字符串

a)以\wiki

开头

b)不包含:

以下是文字:

/wiki/Template:Kevin_Bacon
/wiki/Category:Best_Miniseries_or_Television_Movie_Actor_Golden_Globe_winners
/wiki/Al_Pacino
/wiki/Paul_Giamatti
/wiki/Kevin_Costner
/wiki/Kevin_Costner
/wiki/Michael_Douglas
/wiki/Mark_Ruffalo
/wiki/Idris_Elba
/wiki/Bryan_Cranston
/wiki/Alexander_Skarsg%C3%A5rd
/wiki/Biblioteca_Nacional_de_Espa%C3%B1a
/wiki/Template:Kevin_Bacon
https://hy.wikipedia.org/wiki/%D5%94%D6%87%D5%AB%D5%B6_%D4%B2%D5%A5%D5%B5%D6%84%D5%B8%D5%B6

输出必须分组,即我应该得到这些字符串的列表(或元组):

/wiki/Al_Pacino
/wiki/Paul_Giamatti
/wiki/Kevin_Costner
/wiki/Kevin_Costner
/wiki/Michael_Douglas
/wiki/Mark_Ruffalo
/wiki/Idris_Elba
/wiki/Bryan_Cranston
/wiki/Alexander_Skarsg%C3%A5rd
/wiki/Biblioteca_Nacional_de_Espa%C3%B1a

这是我提取字符串的尝试:

a)使用否定的前瞻: 这个想法是不要选择后跟:的字符串 r^/wiki/.*(?!:).* 但是,上面的代码仍然选择带有:/wiki/Template:Kevin_Bacon

的字符串

b)强制正则表达式不选择: ^/wiki/.*[^:].* 但是,上面的代码仍然选择带有:/wiki/Template:Kevin_Bacon

的字符串

c)使用量词指定:应该出现0次 ^/wiki/.*:{0}.*$ 但是,上面的代码仍然选择带有:/wiki/Template:Kevin_Bacon

的字符串

我有两个问题:

a)我非常喜欢regex。有人可以解释以上尝试有什么问题吗?

b)如何使用上述方法解决问题?

我将在python中使用regex模块。按照SO的指南,我尝试在regex网站上调试regex101。这是链接:https://regex101.com/r/Wt40Cz/1

衷心感谢您的帮助。预先感谢。

2 个答案:

答案 0 :(得分:2)

您的正则表达式是错误的。

^/wiki/.*[^:].*

解析如下:

  • ^:匹配行的开头
  • /wiki/:匹配文字序列/wiki/
  • .*:匹配零个或多个任意字符
  • [^:]:匹配所有非:的内容
  • .*:匹配零个或多个任意字符

是这样

  1. 匹配行的开头(确定)
  2. 匹配文字/wiki/(确定)
  3. 匹配该行的其余部分(呃,哦)
  4. 回溯字符并匹配“不是:的任何字符,只要最后一个字符不是:(嗯...)
  5. 不匹配任何字符,即零个或多个字符

因此,由于.*,您的正则表达式最终与整行匹配,除非最后才检查:

现在看看正确的表达式是什么

^\/wiki\/[^:]+$
  • ^:匹配行的开头
  • /wiki/:匹配文字序列/wiki/
  • [^:]+:匹配不是:的任何一个或多个
  • $:匹配行尾

    1. 匹配行的开头(确定)
    2. 匹配文字/wiki/(确定)
    3. 匹配该行的其余部分,除非它包含:,在这种情况下它将失败
    4. 匹配行尾

希望能帮助您更好地分解问题。我强烈建议https://www.regex101.com用于构建和测试正则表达式(它具有与Python兼容的regex模式),因为它还包括对regex引擎正在逐步进行操作的解释。

编辑:要回答您的第二个问题,我看不到其他构建此表达式的明智方法。不要使用前行或量词,这不是它的目的。

答案 1 :(得分:1)

尝试正则表达式^\/wiki\/[^:]*?$

它将匹配以/wiki/开头的字符串,然后此[^:]*?将匹配没有:的字符,直到结尾$

在您的正则表达式^/wiki/.*[^:].*$中,有两个.*,因此:将与.*中的任何一个一起逸出。因此,[^:]*将是足以捕获一切

Regex