2013-12-22 4 views
15

Я пытаюсь отфильтровать список строк с регулярными выражениями, как показано в this answer. Однако код дает неожиданный результат:Регулярные выражения Python для фильтрации списка строк

In [123]: r = re.compile('[0-9]*') 
In [124]: string_list = ['123', 'a', '467','a2_2','322','21'] 
In [125]: filter(r.match, string_list) 
Out[125]: ['123', 'a', '467', 'a2_2', '322_2', '21'] 

Я ожидал, что выход будет ['123', '467', '21'].

ответ

17

Проблема заключается в том, что ваш шаблон содержит *, квантификатор, будет соответствовать ноль или более цифр. Поэтому, даже если строка не содержит цифры вообще, она будет соответствовать шаблону. Кроме того, ваш шаблон будет соответствовать цифрам везде, где они встречаются во входной строке, то есть a2 по-прежнему является действительным совпадением, потому что он содержит цифра.

Попробуйте использовать этот шаблон

^[0-9]+$ 

или более просто:

^\d+$ 

Это будет соответствовать одна или несколько цифр. Начальные (^) и конечные ($) якоря гарантируют, что в строке не будут находиться символы других.

7

Есть ли необходимость в Regex здесь? У вас str.isdigit:

>>> string_list = ['123', 'a', '467','a2_2','322','21'] 
>>> [x for x in string_list if x.isdigit()] 
['123', '467', '322', '21'] 
>>> 
+0

В этом конкретном примере, нет нет, но я хотел бы знать, почему он не работает так, как я ожидал. –

+2

Что произойдет, скажем, '1e6'? :) –

+0

@Allendar '>>> '23e1'.isdigit()' is 'False' –

Смежные вопросы