我想创建一个(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。
感谢您的阅读。
布赖恩
答案 0 :(得分:1)
我至少改变了一件事,那就是在正则表达式周围添加单词边界锚点,否则它会匹配任何文本中的每一个字母:
rex = re.compile(r'(\(?\b%s\)|\b%s\b\.?)' % (numex, numes), re.I|re.M)
这有点帮助,但当然任何一个或两个字母的单词仍然匹配。
您可能希望将搜索锚定在行的开头;在所有这些字符应该是第一件事就行了(除了可能是空格)。负面的lookbehind不会在Python中说,因为Python不支持可变长度的lookbehind,所以你可以在匹配的括号外添加它:
rex = re.compile(r'^\s*(\(?%s\)|%s\b\.?)' % (numex, numex), re.I|re.M)
当然,现在你必须查看匹配对象的group(1)
才能获得实际匹配而不是前导空格。
你仍然会匹配太多(例如以I thought so
或It was a dark and stormy night
开头的句子,但你的规则允许这样做,我想你已经知道了这一点。
答案 1 :(得分: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)
欢迎添加,更改和建议。