Я ищу регулярное выражение, которое превращает эту строку:

'foo bar 12 3.4 32 1992 112 0433 3312 182470921358 3,412 some text'

В эту строку:

'foo bar    1992      some text'

То есть я хочу удалить все цифры из строки, кроме тех, которые представляют годы (1000 - 2999).

Я искал функцию регулярного выражения, которая делает что-то вроде

(<PATTERN1> except <PATTERN2>)

Я смог придумать <PATTERN1> и <PATTERN2>:

<PATTERN1> -> \b[0-9(.,)+]*\b
<PATTERN2> -> \b[12]{1}[0-9]{3}\b

В коде:

>>> import re
>>> s = 'foo bar 12 3.4 32 1992 112 0433 3312 182470921358 3,412 some text'
>>> re.sub(r'\b[0-9(.,)+]*\b', '', s)
'foo bar          some text'
>>> import re
>>> print re.sub(r'\b[0-9(.,)+]*\b', '', s)
foo bar          some text
>>> re.sub(r'\b[12]{1}[0-9]{3}\b', '', s)
'foo bar 12 3.4 32  112 0433 3312 182470921358 3,412 some text'

Но я не смог собрать их вместе. Позитивный взгляд сзади тоже не помогает.

Этот:

(?<=\b[12]{1}[0-9]{2})[0-9(.,)+]{1}\b

Соответствует только 2 из 1992 вместо 1992 полностью.

Какие-либо предложения?

2
dr. atom 16 Дек 2015 в 09:44

3 ответа

Лучший ответ

Вы можете использовать это регулярное выражение на основе отрицательного взгляда:

>>> s = 'foo bar 12 3.4 32 1992 112 0433 3312 182470921358 3,412 some text'
>>> print re.sub(r'\b(?!(\D\S*|[12][0-9]{3})\b)\S+\b', '', s)
'foo bar    1992      some text'

Демо RegEx

(?!(\D\S*|[12][0-9]{3}) будет соответствовать всему, что начинается с нецифровой или не годовой цифры за пределами 1000-2999 диапазона.

2
anubhava 16 Дек 2015 в 07:01
import re
s = 'foo bar 12 3.4 32 1992 112 0433 3312 182470921358 3,412 some text'
p = r'((\b[0-9][0-9.,]{0,2}\b)|(\b[0-9][0-9.,]{4,}\b))|(\b[03-9][\d]{3}\b)'
print re.sub(p, '', s)

Выход:

'foo bar    1992      some text'

Глупый метод.

0
titor 16 Дек 2015 в 08:36

Вы можете просто использовать следующий подход и определить, попадает ли каждое число в правильный диапазон. Это позволит легко изменить диапазон номеров, если это необходимо:

import re

def year(match):
    try:
        if 1000 <= int(match.group(1)) <= 2999:
            return match.group(1)
    except ValueError, e:
        pass
    return ''


text = 'foo bar 12 3.4 32 1992 112 0433 3312 182470921358 3,412 some text'
print re.sub('([0-9,.]+)', year, text)

Это отобразит:

foo bar    1992      some text
1
Martin Evans 16 Дек 2015 в 07:11