2010-07-17 2 views
1

Я хочу, чтобы модель рельсов исключала определенные шаблоны: пробеги двух или более пробелов.validates_format_of для исключения определенных шаблонов

User.name = "Harry Junior Potter" действителен, но User.name = "Harry Junior Potter" не является (два пространства между Гарри и младшим). Это во избежание кражи личных данных, где эти два имени отображаются одинаково (HTML сжимает пробелы пробелов).

Иными словами: Разрешены: [0-9A-z_-] и '\s только в серии из одного'.

Моя регулярное выражение слишком бедна, чтобы выработать такое регулярное выражение, это то, что у меня есть (с отрицательным lookahead, но это не соответствует правильно

/([0-9A-z_\-])(\s(?!\s))?/ 

Примечание:. Before_validation крюк уже полоса () s все элементы, поэтому пробелы в начале или конце строки не являются проблемой.

ответ

1

Во-первых, [A-z] - это ошибка. Это эквивалентно

[A-Z\[\\\]^_`a-z] 

... и я уверен, что это не то, что вы имели в виду. Вы должны указать два диапазона отдельно: [A-Za-z]. Но в этом случае вы также соответствуете цифрам и подчеркиванию, поэтому вы можете использовать \w, как @Sjuul: [\w-]+. Это делает ваше регулярное выражение

/^[\w-]+(?: [\w-])*$/ 

Конечно, это будет соответствовать глупые вещи, как -- - ---, и это не соответствовать много реальных имен.Я просто отвечаю на ваш вопрос о разрешении только одного пробела между именами.

+0

Я действительно не понимаю, что вы имеете в виду "и не будет соответствовать многим настоящим именам". Я специально упустил акценты и никаких персонажей ascii, чтобы сосредоточиться на проблеме двойных пространств. (первое тонкое приложение gmy, которое нужно сделать, после этого принимает мое собственное имя, Bèr :) – berkes

+0

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

1

Не намного ли проще заменить "__" with "_"? (Использование символов подчеркивания для отображения пробелов) My Ruby is not это бегло, но должно быть что-то вроде

User.name.replace!(" ", " ") while User.name.contains(" ") 

Тогда вы могли бы использовать это регулярное выражение для проверки остальных

([\w\-]+\s?)+ 
+0

Хороший маршрут, действительно: сжать все пробелы в один. Затем обработчик проверки может искать дубликаты: «Harry__Potter» станет «Harry_Potter», который уже может существовать. Небольшая деталь: я не могу просто искать буквальное пространство, так как в UTF8 возможно много форм пробелов (включая вкладки, строки и т. Д.). – berkes

+0

Вместо этого вы можете использовать 'gsub':' User.name.gsub! (/ \ s + /, '') '. Это приведет к преобразованию других пробелов в пространства в дополнение к их свертыванию. Кстати, TAB и linefeed являются символами ASCII, поэтому '\ s' будет соответствовать им. Там * есть * много символов, отличных от ASCII, но у них не было бы имени бизнеса; Я бы просто их запретил. –

+0

Приятно видеть, что вы получаете здесь несколько хороших идей. –

0

Я хотел бы предложить альтернативный маршрут .. очень странно один на самом деле. Если вы находитесь на хрусте времени и не потрудитесь иметь дополнительный столбец в своей существующей таблице, я бы предложил создать пул пользователя-имени. Я знаю, что это слишком много для вашей проблемы. Но я предпочитаю делать свои чеки таким образом. Вместо того, чтобы проверять новое имя пользователя на уже сохраненное (и ломать голову над всеми этими беспорядочными регулярными выражениями), я просто проверяю новый slug на сохраненный slug (который, кстати, обрабатывает все эти беспорядочные регулярные выражения для вас). Вы можете проверить to_slug: http://github.com/ludo/to_slug

Слизни используются главным образом для отфильтровывания опасных символов из URL-адресов. Почему бы не использовать то же самое для проверки имен пользователей? Он также обрабатывает символы Unicode.

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

Простая проверка в моих выходов консоли:

>> "Harry Junior Potter".to_slug 
=> "harry-junior-potter" 
>> "Harry Junior Potter".to_slug 
=> "harry-junior-potter" 
>> "Harry   Junior   Potter".to_slug 
=> "harry-junior-potter" 
>> "Harry(junior(potter))".to_slug 
=> "harry-junior-potter" 
>> "Harry_Junior_Potter".to_slug 
=> "harry_junior_potter" 

Итак, теперь, если и только если пробкового проверяет пользователь может хранить его имя.

+1

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

+0

Единственным недостатком этого является наличие дополнительного столбца в базе данных. Это просто вопрос компромисса (время и хранение). Если у вас достаточно времени, используйте проверку регулярных выражений. Если не использовать слизняки. Я лично стараюсь избегать регулярных выражений. Тем не менее, если вы планируете не использовать вышеупомянутое решение, я предлагаю проверить http://rubular.com. Это упрощает проверку ваших регулярных выражений. –

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