【问题标题】:re to identify range from stringre 从字符串中识别范围
【发布时间】:2013-12-20 13:15:08
【问题描述】:

如果我们有字符串,如何编写和正则表达式从字符串中获取列表:

value = '88-94'
value = '88 to 94'
value = '88'
value = '88-94, 96-108'

结果应该是:

[88, 89, 90, 91, 92, 93, 94]
[88, 89, 90, 91, 92, 93, 94]
[88]
[88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108]

编程语言是python2.7

这是适用于 python2.7 和正则表达式的有效解决方案,但必须检查最后一个具有单个值作为单独案例的案例:

>>> import regex
>>> m = regex.match(r"(?:(?P<digits>\d+).(?P<digits>\d+))", "88-94")
>>> a = m.captures("digits")
>>> a
['88', '94']
>>> m = regex.match(r"(?:(?P<digits>\d+).(?P<digits>\d+))", "88 94")
>>> a = m.captures("digits")
>>> a
['88', '94']
>>> range(int(a[0]), int(a[1])+1)
[88, 89, 90, 91, 92, 93, 94]
>>> 

这是一个解决上述情况的解决方案,但是 88-94、96-98 等呢

>>> import re
>>> a = map(int, re.findall(r'\d+', '88-94'))
>>> range(a[0], a[-1]+1)
[88, 89, 90, 91, 92, 93, 94]
>>> a = map(int, re.findall(r'\d+', '88 94'))
>>> range(a[0], a[-1]+1)
[88, 89, 90, 91, 92, 93, 94]
>>> a = map(int, re.findall(r'\d+', '88'))
>>> range(a[0], a[-1]+1)
[88]
>>> 

几乎涵盖所有案例的解决方案:

>>> import re
>>> a = map(int, re.findall(r'\d+', '88-94, 96-108'))
>>> c = zip(a[::2], a[1::2])
>>> [m for k in [range(i,j+1) for i, j in c] for m in k]
[88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108]
>>> a = map(int, re.findall(r'\d+', '88-94, 96-108, 125 129'))
>>> c = zip(a[::2], a[1::2])
>>> [m for k in [range(i,j+1) for i, j in c] for m in k]
[88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 125, 126, 127, 128, 129]
>>> a = map(int, re.findall(r'\d+', '88-94, 96-108, 125 129, 132 to 136'))
>>> c = zip(a[::2], a[1::2])
>>> [m for k in [range(i,j+1) for i, j in c] for m in k]
[88, 89, 90, 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 125, 126, 127, 128, 129, 132, 133, 134, 135, 136]
>>> 

任何人都可以提出反对或投票赞成关闭的理由吗?

任何帮助将不胜感激,任何人都可以建议如何更新问题我不要求替代解决方案,因为我知道如何拆分和循环甚至重新剥离数字和循环,我的问题是如何使用 re 单如果可能的话?答案可能是“否”,但不是题外话。

【问题讨论】:

标签: python regex list parsing


【解决方案1】:
import re

def get_numbers(value):
    value = re.sub(r'^(\d+)$', r'\1-\1', value) # '88' -> '88-88'
    start, stop = map(int, re.findall(r'\d+', value))
    return range(start, stop+1)

print get_numbers('88-94')
print get_numbers('88 to 94')
print get_numbers('88')

输出:

[88, 89, 90, 91, 92, 93, 94]
[88, 89, 90, 91, 92, 93, 94]
[88]

【讨论】:

    【解决方案2】:
    range(*map(int,mystring.split("-")))
    

    不需要正则表达式

    【讨论】:

    • int 丢失:range(*map(int, mystring.split("-")))
    • 而当mystring = '10'时,会产生[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    • 我不小心删除了我的评论,但是当有多个-时不会失败,如`"3-4-5-6-7"?
    • @SteveP。这是一个有效的范围吗? OP想要从字符串中识别范围。
    • @thefourtheye 不,但它是一个有效的字符串......这假设正确,两个输入数字字符串,但其他一切都失败。
    猜你喜欢
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    相关资源
    最近更新 更多