Ошибка при фильтрации списка строк с помощью re.match
Я хотел бы отфильтровать список строк в python с помощью regex. В следующем случае сохраняются только файлы с расширением ".npy".
Код, который не работает:
import re
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
regex = re.compile(r'_x\d+_y\d+\.npy')
selected_files = filter(regex.match, files)
print(selected_files)
Это же регулярное выражение работает для меня в Ruby:
selected = files.select { |f| f =~ /_x\d+_y\d+\.npy/ }
Что не так с кодом Python?
Ответы
Ответ 1
selected_files = filter(regex.match, files)
re.match('regex')
невероятно похож на re.search('^regex')
или text.startswith('regex')
, но имеет регулярное выражение. Он только проверяет, начинается ли строка с регулярного выражения.
Поэтому вместо этого используйте re.search()
:
import re
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
regex = re.compile(r'_x\d+_y\d+\.npy')
selected_files = list(filter(regex.search, files))
# The list call is only required in Python 3, since filter was changed to return a generator
print(selected_files)
Выход:
['/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.npy']
И если вы просто хотите получить все файлы .npy
, просто используйте str.endswith()
:
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
selected_files = list(filter(lambda x: x.endswith('.npy'), files))
print(selected_files)
Ответ 2
Просто используйте search
- поскольку совпадение начинается с начала от начала до конца (т.е. Целого) строки и поиска в любом месте строки.
import re
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
regex = re.compile(r'_x\d+_y\d+\.npy')
selected_files = filter(regex.search, files)
print(selected_files)
Output-
['/a/b/c/la_seg_x005_y003.npy', '/a/b/c/la_seg_x004_y003.npy', '/a/b/c/la_seg_x003_y003.npy']
Ответ 3
re.match()
ищет совпадение в начале строки. re.search()
этого вы можете использовать re.search()
.
Ответ 4
Если вы соответствуете, шаблон должен охватывать весь вход. Либо расширяйте регулярное выражение:
regex = re.compile(r'.*_x\d+_y\d+\.npy')
Что бы соответствовало:
['/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.npy']
Или используйте re.search, который
просматривает строку, которая ищет первое место, где шаблон регулярного выражения создает совпадение [...]