Назначение {1} в этом регулярном выражении для соответствия протоколам URL

StackOverflow https://stackoverflow.com/questions/13470

  •  08-06-2019
  •  | 
  •  

Вопрос

Я читал этот вопрос о том, как анализировать URL-адреса веб-страниц, и у меня возник вопрос о принятый ответ который предложил это решение:

((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)

Решение было предложено csmba и он приписал это regexlib.com.Фух.Зачеты сделаны.

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

В чем смысл этого {1}?Это означает "точно один из предыдущей группы", верно?Разве это не поведение группировки по умолчанию в регулярном выражении?Будет ли это выражение каким-либо образом изменено, если {1} были удалены?

Если бы я увидел это от коллеги, я бы указал на его или ее ошибку, но когда я пишу это, ответ оценивается как 6, а выражение на regexlib.com оценивается как 4 из 5.Так, может быть, я что-то упускаю?

Это было полезно?

Решение

@Джефф Этвуд, ваша интерпретация немного неточна - значение {1} совпадает ровно один раз, но никак не влияет на "захват" - захват происходит из-за скобок в скобках - фигурные скобки указывают только количество раз, когда шаблон должен соответствовать источнику - один раз, как вы говорите.

Я согласен с @Marius, даже если его ответ немного лаконичен и может показаться легкомысленным.Регулярные выражения сложны, если кто-то не привык их использовать, и {1} в вопросе не совсем ошибка - в системах, которые его поддерживают, это означает "ровно одно совпадение".В этом смысле он на самом деле ничего не делает.

К сожалению, вопреки удаленному сообщению, это не мешает регулярному выражению соответствовать http://http://example.org, поскольку символ \S+ в конце будет соответствовать одному или нескольким символам, не содержащим пробелов, включая http://example.org в http://http://example.org (проверено с использованием Python 2.5, на всякий случай, если мое чтение регулярного выражения было отключено).Итак, приведенное регулярное выражение на самом деле не самое лучшее.Я не эксперт по URL-адресам, но, вероятно, что-то, ограничивающее появление ":"s и "//"s после первого, было бы необходимо (но вряд ли достаточно) для обеспечения хороших URL-адресов.

Другие советы

@Роб:Я не согласен.Чтобы обеспечить выполнение того, о чем вы просите, я думаю, вам нужно было бы использовать negative-look-behind, что возможно, но, безусловно, не связано с использованием {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 >

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

Я не думаю, что {1} имеет какую-либо допустимую функцию в этом регулярном выражении.

(** адрес электронной почты:|(news|(ht|f)tp(s?))://){1}**

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top