регулярное выражение для соответствия максимум 4 пробелам - PullRequest
3 голосов
/ 02 ноября 2008

У меня есть регулярное выражение, соответствующее имени человека.

Пока у меня есть ^ ([a-zA-Z \ '\ s] +) $, но я бы хотел добавить проверку, чтобы разрешить максимум 4 пробела. Как я могу изменить это, чтобы сделать это?

Редактировать: я имел в виду 4 пробела в любом месте строки

Ответы [ 7 ]

11 голосов
/ 02 ноября 2008

Не пытайтесь регулярно проверять правильность имени. Люди могут называть себя так, как им нравится. Это может включать ЛЮБОГО персонажа. Тот факт, что вы живете где-то, где используется только английский, не означает, что все люди, которые используют вашу систему, будут иметь английские имена. Нам даже пришлось сделать поле имени в нашей системе Unicode. Это единственный тип Unicode в базе данных.

Если вам не все равно, мы фактически разделяем имя в "" и сохраняем каждую часть имени как отдельную запись, но у нас есть некоторые очень специфические требования, которые означают, что это хорошая идея.

PS. У моей мачехи есть 5 пробелов в ее имени.

6 голосов
/ 02 ноября 2008
^                    # Start of string
(?!\S*(?:\s\S*){5})  # Negative look-ahead for five spaces.
([a-zA-Z\'\s]+)$     # Original regex

или в одну строку:

^(?!(?:\S*\s){5})([a-zA-Z\'\s]+)$

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

5 голосов
/ 02 ноября 2008

Винт регулярное выражение.

Использование регулярного выражения в данном случае создает проблему для решения, а не просто решает проблему.

Эта задача должна быть «легкой» даже для начинающего программиста, а новая идея регулярных выражений осквернила наш разум!

1: Get Input    
2: Trim White Space
3: If this makes sence, trim out any 'bad' characters. 
4: Use the "split" utility provided by your language to break it into words
5: Return the first 5 Words. 

РАКЕТНАЯ НАУКА.

ответ

что вы имеете в виду ввернуть регулярное выражение? Вы, очевидно, программист VB. Regex - самый эффективный способ работы со строками. Изучите их.

Нет. Php, немного поигравший с ruby, теперь безумно зацикливается на perl.

Есть некоторые вещи (например, в этом случае), когда основанная на регулярных выражениях альтернатива вычислительно и логически экспоненциально чрезмерно сложна для задачи.

Я анализирую все исходные файлы php с помощью regex, я не новичок в их использовании.

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

Конечно, я мог бы выполнять все шаги 2-5 с регулярным выражением, но они были бы простыми и атомарными, без странного синтаксиса обратного отслеживания или потенциала для рекурсивного поиска.

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

Я вижу, что кто-то отметил мой пост как оскорбительный, я несколько недоволен, я не могу отметить этот факт как оскорбительный для меня. ;)

Доказательство пудинга:

sub getNames{
    my @args = @_;
    my $text = shift @args;
    my $num  = shift @args;

    # Trim Whitespace from Head/End
    $text =~ s/^\s*//;
    $text =~ s/\s*$//;

    # Trim Bad Characters (??)
    $text =~ s/[^a-zA-Z\'\s]//g;

    # Tokenise By Space 
    my @words = split( /\s+/, $text );

    #return 0..n 
    return @words[ 0 .. $num - 1 ];
} ## end sub getNames

print join ",", getNames " Hello world     this is a    good test", 5;
>> Hello,world,this,is,a

Если у кого-то есть что-то двусмысленное, как это работает, я буду рад объяснить это им. Заметил, что я все еще делаю это с регулярными выражениями. На других языках я бы использовал их родные функции «отделки», если это возможно.


Боллс ->

Я впервые попробовал этот подход. Это твой мозг на регулярных выражениях. Дети, не делайте регулярных выражений.


Это может быть хорошим началом

/([^\s]+
    (\s[^\s]+
      (\s[^\s]+
        (\s[^\s]+
          (\s[^\s]+|)
         |)
       |)
    |)
  )/ 

(зачеркнуто для ясности)

/([^\s]+(\s[^\s]+(\s[^\s]+(\s[^\s]+|)|)|))/ 

(факт)

Я использовал [^\s]+ здесь вместо вашей комбинации A-Z для краткости, но дело здесь во вложенных необязательных группах

т.е.:

(Hello( this( is( example))))
(Hello( this( is( example( two)))))
(Hello( this( is( better( example))))) three
(Hello( this( is()))))
(Hello( this()))
(Hello())

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

Если вы хотите читаемый код:

  $word = '[^\s]+'; 
  $regex = "/($word(\s$word(\s$word(\s$word(\s$word|)|)|)|)|)/"; 

(он привязывает к (захватить |) мантру "получить это или ничего не получить")

3 голосов
/ 02 ноября 2008

@ Сэр Психо: будьте осторожны в своих предположениях здесь. Как насчет дефисных имен? Пунктирные имена (например, Брайан Р. Бонди) и т. Д.?

2 голосов
/ 02 ноября 2008

Вот ответ, который вы, скорее всего, ищете:

^[a-zA-Z']+(\s[a-zA-Z']+){0,4}$

Это говорит (на английском языке): «От начала до конца, сопоставьте одну или несколько букв, также может быть пробел, за которым следует другое« имя »до четырех раз».

Кстати: почему вы хотите, чтобы у них были апострофы в любом месте имени?

2 голосов
/ 02 ноября 2008

^([a-zA-Z']+\s){0,4}[a-zA-Z']+$

Предполагается, что вы хотите 4 пробела внутри этой строки (т. Е. Вы обрезали ее)

Изменить: Если вы хотите, чтобы в любом месте было 4 пробела, я бы порекомендовал не использовать регулярные выражения - вам лучше использовать substr_count (или эквивалент на вашем языке).

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

0 голосов
/ 27 июня 2013

Соответствует нескольким пробелам, за которыми следуют два символа в конце строки.

Сопутствующая проблема ----

Из строки удалите завершающие 2 символа, которым предшествуют несколько пробелов ... Например, если столбец содержит эту строку - «Это длинная строка с 2 символами в конце AB» затем AB следует удалить, сохранив предложение.

Решение ----

select 'This is a long string with 2 chars at the end AB' as "C1", regexp_replace('This is a long string with 2 chars at the end AB', '[[[:space:]][a-zA-Z][a-zA-Z]]*$') as "C2" from dual;

Выход ----

C1

This is a long string with 2 chars at the end AB

C2

This is a long string with 2 chars at the end

Анализ ---- регулярное выражение указывает - сопоставьте и замените ноль или более вхождений (*) пробела ([: space:]) с последующей комбинацией двух символов ([a-zA-Z] [a-zA-Z]) в конце линия.

Надеюсь, это полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...