Назначение {1} в этом регулярном выражении для соответствия протоколам URL
Я читал этот вопрос о том, как анализировать URL-адреса на веб-страницах и имел вопрос о принятом ответе , который предложил это решение:
((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)
Решение было предложено csmba, и он присвоил его regexlib.com. Уф. Сделанные кредиты.
Я думаю, что это довольно наивное регулярное выражение, но это прекрасная отправная точка для создания чего-то лучшего. Но, мой вопрос таков:
В чем смысл {1}
? Это означает "точно одну из предыдущих группировок", верно? Разве это не поведение по умолчанию для группировки в регулярном выражении? Не изменилось бы выражение, если бы {1}
были удалены?
Если бы я увидел это от коллеги, я бы указал на его или ее ошибку, но, как я пишу, ответ оценивается в 6, а выражение на regexlib.com оценивается в 4 из 5. Так что, возможно, я отсутствую что-то?
Ответы
Ответ 1
@Jeff Atwood, ваша интерпретация немного неактивна - {1} означает совпадение ровно один раз, но не влияет на "захват" - захват происходит из-за парен - фигурные скобки указывают только количество раз шаблон должен соответствовать источнику - один раз, как вы говорите.
Я согласен с @Marius, даже если его ответ немного короткий и может оторваться как легкомысленный. Регулярные выражения жесткие, если они не используются для их использования, а {1} в вопросе - не совсем ошибка - в системах, которые его поддерживают, это означает "ровно одно совпадение". В этом смысле он ничего не делает.
К сожалению, в отличие от удаленной записи, он не поддерживает регулярное выражение http://http://example.org
, так как \S + в конце будет соответствовать одному или нескольким символам без пробелов, включая http://example.org
in http://http://example.org
(проверено с использованием Python 2.5, на всякий случай, когда чтение регулярного выражения отключено). Таким образом, данное регулярное выражение не является лучшим. Я не эксперт по URL, но, вероятно, что-то ограничивающее появление ":" s и "//" после первого (но вряд ли достаточного) для обеспечения хороших URL-адресов.
Ответ 2
@Rob: Я не согласен. Чтобы обеспечить соблюдение того, о чем вы просите, я думаю, вам нужно использовать отрицательный внешний вид, что возможно, но, конечно же, не связано с использованием {1}. Ни одна из версий регулярного выражения не является проблемой.
Чтобы код говорил:
tibook 0 /home/jj33/swap > cat text
Text this is http://example.com text this is
Text this is http://http://example.com text this is
tibook 0 /home/jj33/swap > cat p
#!/usr/bin/perl
my $re1 = '((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)';
my $re2 = '((mailto\:|(news|(ht|f)tp(s?))\://)\S+)';
while (<>) {
print "Evaluating: $_";
print "re1 saw \$1 = $1\n" if (/$re1/);
print "re2 saw \$1 = $1\n" if (/$re2/);
}
tibook 0 /home/jj33/swap > cat text | perl p
Evaluating: Text this is http://example.com text this is
re1 saw $1 = http://example.com
re2 saw $1 = http://example.com
Evaluating: Text this is http://http://example.com text this is
re1 saw $1 = http://http://example.com
re2 saw $1 = http://http://example.com
tibook 0 /home/jj33/swap >
Итак, если есть разница между двумя версиями, это, похоже, не та, которую вы предлагаете.
Ответ 3
Я не думаю, что это имеет какую-то цель. Но поскольку RegEx практически невозможно понять/разложить, люди редко указывают на ошибки. Вероятно, поэтому никто больше не указал на это.
Ответ 4
Я не думаю, что {1} имеет любую действительную функцию в этом регулярном выражении.
(** электронной почты: |? (Новости | (ХТ | е) ф (s))://) {1} **
Вы должны прочитать это как: "захватить материал в parens ровно один раз". Но мы не заботимся об этом, чтобы использовать его позже, например, $1 взамен. Так что это бессмысленно.