【问题标题】:How to create regex for inline ordered list?如何为内联有序列表创建正则表达式?
【发布时间】:2014-08-16 19:36:11
【问题描述】:

我有一个表单域,其中大部分只包含内联有序列表:

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')

P.S.:这里我使用 Django 框架中的 RegexValidator 类来验证表单字段值。

【问题讨论】:

  • 你能再具体一点吗?你想要什么结果?另外,什么是字符串,什么不是?你的意见是什么?
  • 使用捕获组:"\d. ([^\d]+)"gDemo

标签: python regex django


【解决方案1】:

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

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

以下是新功能:

  • (?:^|\s) 与交替之间的回溯匹配。这里我们使用(?&lt;!\S) 代替,以断言我们不在非空白字符前面。
  • \d{1,2}\.\s 不必在非捕获组中。
  • (.+?)(?=(?:, \d{1,2}\.)|$) 太笨重了。我们将此位更改为:
    • ( 捕获组
    •  (?:
    •    (?! Negative lookahead:断言我们的位置是NOT
    •       ,\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}\.),?[^,]*)+)')

【讨论】:

  • @SultanAlotaibi 我明白你现在的意思了,我根据问题中的测试用例设计了正则表达式,对不起。请参阅我更新的答案,它说明了实际的列表结构。
  • @SultanAlotaibi 很高兴为您提供帮助!
【解决方案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.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多