如何为内联有序列表创建正则表达式?

2024-04-19 19:25:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个表单字段,其中大多数字段只包含内联排序列表:

1. This item may be contain characters, symbols or numbers. 2. And this item also...

以下代码不适用于用户输入验证(用户只能输入内联排序列表):

definiton_re = re.compile(r'^(?:\d\.\s(?:.+?))+$')
validate_definiton = RegexValidator(definiton_re, _("Enter a valid 'definition' in format: 1. meaning #1, 2. meaning #2...etc"), 'invalid')

注意:这里我使用Django框架中的RegexValidator类来验证表单字段值


Tags: 用户re列表排序bethisitem单字
2条回答

这是我的解决办法。效果不错

input = '1. List item #1, 2. List item 2, 3. List item #3.'
regex = re.compile(r'(?:^|\s)(?:\d{1,2}\.\s)(.+?)(?=(?:, \d{1,2}\.)|$)')
# Parsing.
regex.findall(input) # Result: ['List item #1', 'List item 2', 'List item #3.']
# Validation.
validate_input = RegexValidator(regex, _("Input must be in format: 1. any thing..., 2. any thing...etc"), 'invalid')
validate_input(input) # No errors.

Nice solution from OP.为了更进一步,让我们做一些正则表达式优化/打高尔夫球

(?<!\S)\d{1,2}\.\s((?:(?!,\s\d{1,2}\.),?[^,]*)+)

以下是最新消息:

  • (?:^|\s)与交替之间的回溯匹配。这里我们使用(?<!\S)来声明我们没有在非空白字符前面
  • \d{1,2}\.\s不必位于非捕获组中
  • (.+?)(?=(?:, \d{1,2}\.)|$)太大了。我们将此位更改为:
    • (捕获组
    • (?:
    • (?!消极前瞻:断言我们的立场是而不是
    • ,\s\d{1,2}\.逗号、空格字符,然后是列表索引
    • )
    • ,?[^,]*以下是有趣的优化:
      • 如果有逗号,我们就匹配它。因为我们从前瞻性断言中知道,此位置不会启动新的列表索引。因此,我们可以安全地假设非逗号序列的剩余位(如果有)与下一个元素无关,因此我们使用*量词对其进行滚动,并且没有回溯
      • 这是对{}的重大改进
    • )+继续重复该组,直到负前瞻断言失败
    • )

你可以用它来代替the other answer中的正则表达式,这里是一个regex demo


不过,乍一看,在解析时使用re.split()可以更好地解决这个问题:

input = '1. List item #1, 2. List item 2, 3. List item #3.';
lines = re.split('(?:^|, )\d{1,2}\. ', input);
 # Gives ['', 'List item #1', 'List item 2', 'List item #3.']
if lines[0] == '':
  lines = lines[1:];
 # Throws away the first empty element from splitting.
print lines;

这是一个online code demo

不幸的是,对于验证,您必须遵循正则表达式匹配方法,只需在楼上编译正则表达式:

regex = re.compile(r'(?<!\S)\d{1,2}\.\s((?:(?!,\s\d{1,2}\.),?[^,]*)+)')

相关问题 更多 >