Пожалуйста, объясните это регулярное выражение Perl - PullRequest
1 голос
/ 19 декабря 2008
    $rowfetch =~ s/['-]//g; #All chars inside the [ ] will be filtered out.
    $rowfetch =~ m/(\w+), ?(.)/;
    printf $fh lc($2.$1);

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

Оно берет имя вроде Паризи, Кеннета и печатает kparisi

Известно:
s / = заменитель
m / = match


Я попытался найти остальное, но не смог найти ничего, что действительно помогло бы объяснить это.

Я также не понял как предполагается, что = ~ равно true или false, но в этой ситуации он модифицирует строку.

Ответы [ 9 ]

22 голосов
/ 19 декабря 2008

Мне очень полезен модуль YAPE::Regex::Explain -

C:\>perl -e "use YAPE::Regex::Explain;print YAPE::Regex::Explain->new(qr/['-])->explain;"
The regular expression:

(?-imsx:['-])

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  ['-]                     any character of: ''', '-'
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------



C:\>perl -e "use YAPE::Regex::Explain; print YAPE::Regex::Explain->new(qr/(\w+), ?(.)/)->explain;"
The regular expression:

(?-imsx:(\w+), ?(.))

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    \w+                      word characters (a-z, A-Z, 0-9, _) (1 or
                             more times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
  ,                        ','
----------------------------------------------------------------------
   ?                       ' ' (optional (matching the most amount
                           possible))
----------------------------------------------------------------------
  (                        group and capture to \2:
----------------------------------------------------------------------
    .                        any character except \n
----------------------------------------------------------------------
  )                        end of \2
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------

C:\>
10 голосов
/ 19 декабря 2008

Я держу одну из этих шпаргалок на стене моего куба именно для таких случаев. Google для regular expression cheat sheet, чтобы найти других.

Чтобы добавить к тому, что вы уже знаете:

  g -- search globally throughout the string
  + -- match at least one, but as many as possible
  ? -- match 0 or 1
  . -- match any character
 () -- group these together
  , -- a plain comma, no special meaning
 [] -- match any character inside the brackets
 \w -- match any word character

Магия в группировке - выражение соответствия использует группы и помещает их в переменные $ 1 и $ 2. В этом случае $ 1 соответствует слову перед запятой, а $ 2 соответствует первому символу после пробела после запятой.

3 голосов
/ 22 декабря 2008

Скачайте "Regex Coach" и изучите его. Подумайте о покупке "Освоение регулярных выражений", так как он проведет вас через это минное поле. Это одна из лучших набранных книг, которые я когда-либо видел, и она глубоко информативна, но проницательна.

1 голос
/ 13 апреля 2010

Существует отличный веб-интерфейс для YAPE :: Regex :: Explain.

Вот объяснение s / ['-] // g

и для м / (\ w +),? (.) /

1 голос
/ 17 января 2009

Обратите внимание, что данный код не работает, если ввод не в правильном формате. Вот что я бы сделал:

$rowfetch =~ s/[ '-]//g; #All chars inside the [ ] will be filtered out.
if($rowfetch =~ m/(\w+),([a-z])/i) {
    printf $fh lc($2.$1);
}

позиционные переменные $ 1- $ 9 содержат последнее успешное совпадение, но они не сбрасываются в случае неудачных совпадений. Это означает, что если регулярное выражение не совпадает, $ 1 и $ 2 не будут стерты, и вы получите что-то другое, чем вы хотели.

Я также немного изменил регулярное выражение. Первая строка также удаляет пробелы. Поскольку создается впечатление, что вы создаете имена пользователей или адреса электронной почты, вам не нужны пробелы. Вторая строка более строгая, чтобы гарантировать, что $ 2 - это буква, а не какой-либо другой символ. 'I' в конце говорит Perl, чтобы все буквы соответствовали регистру. С этим мне не нужно делать эту вторую часть ([a-zA-Z]).

1 голос
/ 19 декабря 2008

=~ сопоставляет выражение (строку) с левой стороны с регулярным выражением с правой стороны, оно не изменяет строку. В качестве побочного эффекта устанавливаются переменные $1, $2, ... для соответствующих частей в скобках.

В вашем случае первая скобка будет соответствовать "(\w+)" (символы слова повторяются один или несколько раз, а вторая будет соответствовать "(.)" (первая буква данного имени. " ?" выражение будет соответствовать необязательному пробелу.

1 голос
/ 19 декабря 2008

iirc = = означает, что равен совпадению (только если «~» возвращает true, если найдено)

1 голос
/ 19 декабря 2008
$lhs =~ s/foo/bar/g;

Оператор s/ является изменяющим регулярным выражением в Perl - вы сопоставляете LHS с первой частью справа (foo). Вторая часть определяет замену для совпадения в первой части (bar). Так что "Lafooey" переходит к "Labarey".

В вашем вопросе цель состоит в том, чтобы удалить все "и - как в" О'Хэнлоне "и" Чалмонли-Уизерингтон-Смит ".

Тогда это соответствует «Фамилия, Первый символ имени». Скобки помещают значения этих совпадений в переменные $1 и $2.

И печатает строчные буквы "F" + "Фамилия", потому что это значения в $2 и $1.

В конце у вас есть реальное имя пользователя для системы, основанное на реальном имени человека из списка стилей телефонной книги.

1 голос
/ 19 декабря 2008

1-я строка: символы внутри [] ('и -) сопоставляются и заменяются ничем, поэтому удаляются. / g означает глобальный и будет пытаться сопоставить все в строке.

2-я строка: \ w означает символ слова, + означает более одного раза. ? означает 0 или один раз. "" значит что угодно. Таким образом, это означает, что нужно найти любой найденный символ слова более одного раза, за которым следует запятая, затем пробел ноль или один раз, за ​​которым следует один из символов.

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