2012-03-13 5 views
1

У меня есть требование, когда мне нужно сопоставить текст типа «testuser» или «joeperson» с данными типа «test.user» или «joe.person». Я не буду знать, где находится период входящего поиска в фактических данных. Короче говоря, у нас есть URL-адреса, такие как /cart/[имя пользователя, которое может иметь период]/items/, и мне нужно найти все имена пользователей, которые соответствуют этому шаблону.Регулярное выражение для игнорирования символа в поиске

Я использую Django и Python для базы данных MySQL. Я знаю, что могу выполнить запрос Django, например:

User.objects.filter (username__regex = '[какой-то сумасшедший шаблон]'), но это сумасшедший шаблон, в котором мне нужна помощь.

Большое спасибо!

+3

Не могли бы вы просто удалить периоды из строки, а затем выполнить регулярный поиск с помощью вашей новой, дезинфицированной строки? –

+0

Нет, данные в базе данных могут иметь период, и считается правильным. Это поисковый запрос, который не будет иметь период. –

+0

Почему вы не сохраняете данные базы данных в нормированной форме без периода? Регулярные выражения будут медленными. –

ответ

4

Используйте запрос SQL, как следующее:

SELECT * FROM users WHERE REPLACE(username, '.', '') = 'username_without_dots' 

Или в Django:

normalized_name = searchterm.replace('.', '') 
User.objects.raw('SELECT * FROM user WHERE ' 
       'REPLACE(username, '.', '') = %s', 
       [normalized_name]) 
+0

Это будет действительно неэффективно, так как вы не можете иметь индекс для вычисленных столбцов с MySQL. OP, вероятно, должен сделать второй столбец для имен пользователей без периодов, но поскольку он не может изменить свою базу данных ... –

+0

@VincentSavard: Да, это неэффективно, но без возможности изменить данные, я думаю, что это единственный способ (по крайней мере, лучше, чем регулярные выражения;) –

+1

И перекрестите пальцы, чтобы не иметь как paul.omaha paulo.maha в вашем Таблица! – sidyll

0

Попробуйте использовать обратную косую черту, чтобы избежать периода в вашем регулярном выражении, как это:

# This will work for test.user or joe.person 
re.search('(\S+)\.(\S+)', 'test.user') 
0

Отредактировано для более краткого использования '?' vs '{0,1}'

Настоящая проблема, конечно, в том, что кто-то передал вам полевые поиски, не подготовил его правильно, но regEx не обязательно будет намного медленнее, чем цикл вся коллекция с литеральной строкой.

Соответствие RegEx является последовательным, поэтому вам нужно будет сделать что-то подобное для 'testuser' где '.' символы между буквами являются необязательными. Это на самом деле не то, что медленнее regEx, так как он должен терпеть неудачу второй символ не соответствует, и все символы явны, поэтому вы не используете массивный индекс для каждого символа.

r'^t\.?e\.?s\.?t\.?u\.?s\.?e\.?r$' 

Часть, которая имеет значение, - это пространство между вашими обычными персонажами. При> = 0 '.' персонажи, которые вы могли бы сделать. * и, конечно же, я не предполагаю никаких периодов, начинающихся или заканчивающихся. Если вы можете объединиться, вы сможете справиться с этим.

Чтобы создать первый Regex я бы сделать что-то вроде:

user = user.split('') 
userRegEx = '\.?'.join(user) 

#not sure I have the right syntax for the Django arg 

User.objects.filter(username__regex=r'^'+userRegEx+'$') 

Как парень JS, я должен сказать, что я немного озадачен, почему это не произошло в сообществе Python, что обе строки и списки могут иметь метод .join.

+0

Также, если вы можете быть уверены, что первый символ не будет '.' сужение с помощью запроса «начинается с первой буквы» вначале может немного снизить нагрузку. –

+0

Да, вы можете заменить каждый '\. {0,1}' на '\.?'. – alexis

+0

Полностью забыл об использовании одного символа. Я просто подумал об этом как о ленивом toggler для многосимвольных матчей. Я отредактирую. –

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