【问题标题】:Regular expression for matching a variety of types of numbered lists用于匹配各种类型编号列表的正则表达式
【发布时间】:2010-06-27 16:19:02
【问题描述】:

我想创建一个 (PCRE) 正则表达式来匹配所有常用的编号列表,我想分享我的想法并在此过程中收集输入。

我将“列表”定义为一组典型的盎格鲁-撒克逊约定,即

数字

1 2 3
1. 2. 3.
1) 2) 3)
(1) (2) (3)
1.1 1.2 1.2.1
1.1. 1.2. 1.3.
1.1) 1.2) 1.3)
(1.1) (1.2) (1.3)

字母

a b c
a. b. c.
a) b) c)
(a) (b) (c) 
A B C
A. B. C. 
A) B) C)
(A) (B) (C)

罗马数字

i ii iii
i. ii. iii.
i) ii) iii)
(i) (ii) (iii)
I II III
i. ii. iii.
i) ii) iii)
(i) (ii) (iii)

我想知道这组列表有多强,是否还有其他编号约定,以及是否应该删除其中的任何一个。

这是我为解决这个问题而创建的一个正则表达式(在 Python 中):

numex = r'(?:\d{1,3}'\   # 1, 2, 3
    '(?:\.\d{1,3}){0,4}'\ # 1.1, 1.1.1.1
    '|[A-Z]{1,2}'\        # A. B. C.
    '|[ivxcl]{1,6}'       # i, iii, ...

rex = re.compile(r'(\(?%s\)|%s\.?)' % numex, re.I) # re.U?

rex.match("123. Some paragraph")    

我想知道这个正则表达式对于这个问题的适用程度,以及是否有其他替代(正则表达式或其他)解决方案。

顺便说一下,对于我的特定用例,我不希望列表编号超过 25-50。

感谢您的阅读。

布赖恩

【问题讨论】:

    标签: regex enumeration pcre html-lists roman-numerals


    【解决方案1】:

    这是Wikified 解决方案:

     numex = r"""^(?:
          \d{1,3}                 # 1, 2, 3
              (?:\.\d{1,3}){0,4}  # 1.1, 1.1.1.1
        | [B-H] | [J-Z]         # A, B - Z caps at 26.
        | [AI](?!\s)            # Note: "A" and "I" can properly start non-lists
        | [a-z]                 # a - z
        | [ivxcl]{1,6}          # Roman ii, etc
        | [IVXCL]{1,6}          # Roman IV, etc.
        )
        """
    
     rex = re.compile(r'^\s*(\(?%s\)|%s\.?)\s+(.*)'
       % (numex, numex), re.X)
    

    欢迎添加、更改和建议。

    【讨论】:

      【解决方案2】:

      我至少要改变一件事,那就是在你的正则表达式周围添加单词边界锚点,否则它将匹配任何文本中的每个字母:

      rex = re.compile(r'(\(?\b%s\)|\b%s\b\.?)' % (numex, numes), re.I|re.M)
      

      这有点帮助,但当然任何一个或两个字母的单词仍然会匹配。

      您可能希望将搜索锚定在行首;毕竟这些字符应该是第一行(除了空格)。在 Python 中不会出现否定的lookbehind,因为 Python 不支持可变长度的lookbehind,因此您可以将其添加到匹配的括号之外:

      rex = re.compile(r'^\s*(\(?%s\)|%s\b\.?)' % (numex, numex), re.I|re.M)
      

      当然,现在您必须查看匹配对象的 group(1) 才能仅获取实际匹配项,而不是前导空格。

      你仍然会匹配太多(例如以I thought soIt was a dark and stormy night 开头的句子,但你的规则允许这样做,我想你已经意识到了这一点。

      【讨论】:

      • 感谢您的帖子。我刚刚注意到 alpha 误报的这个问题。我想我已经通过(1)通过将字符列表减少到一个字母来简化它,以及(2)使用负零宽度前瞻来解决它。
      猜你喜欢
      • 1970-01-01
      • 2020-11-25
      • 2019-10-15
      • 2020-09-09
      • 2021-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      相关资源
      最近更新 更多