Как сопоставить строку, содержащую точное 3-х кратное вхождение специального символа в perl

Я пробовал несколько методов, чтобы соответствовать слову, которое содержит точную косую черту 3 раза, но не может работать. Ниже приведен пример

@array = qw( abc/ab1/abc/abc a2/b1/c3/d4/ee w/5/a  s/t )
foreach my $string (@array){
    if ( $string =~ /^\/{3}/ ){
          print " yes, word with 3 / found !\n";
          print "$string\n";
    }
    else {
          print " no word contain 3 / found\n";
    }

Я мало пытаюсь, но ни один из них не работает

$string =~ /^\/{3}/;
$string =~ /^(\w+\/\w+\/\w+\/\w+)/;
$string =~ /^(.*\/.*\/.*\/.*)/;

Любой другой способ, которым я могу соответствовать этому типу строки и напечатать строку?

4 ответа

Матч глобально и сравните количество совпадений с 3

if ( ( () = m{/}g ) == 3 ) { say "Matched 3 times" }

где ()= Оператор - это игра контекста, форсирующая контекст списка с правой стороны, но возвращающая количество элементов этого списка, когда скалярный контекст предоставляется с левой стороны.

Если вас не устраивает такой синтаксический растягивающий массив

if ( ( my @m = m{/}g ) == 3 ) { say "Matched 3 times" }

где последующее сравнение оценивает его в скалярном контексте.

Вы пытаетесь сопоставить три подряд / и ваша строка не имеет этого.

Шаблон, который вам нужен (с добавленным пробелом)

^ [^/]* / [^/]* / [^/]* / [^/]* \z

или же

^ [^/]* (?: / [^/]* ){3} \z

Ваша вторая попытка была близка, но с использованием ^ без \z сделал так, чтобы вы проверили строку, начинающуюся с вашего шаблона.


Решения:

say for grep { m{^ [^/]* (?: / [^/]* ){3} \z}x } @array;

или же

say for grep { ( () = m{/}g ) == 3 } @array;

или же

say for grep { tr{/}{} == 3 } @array;

Вы должны соответствовать

  • косая черта
  • в окружении не косых черт (^(?:[^\/]*)
  • повторить матч ровно три раза
  • и заключая всю тройку в начало строки и и в линейные якоря:
$string =~ /^(?:[^\/]*\/[^\/]*){3}$/;
if ( $string =~ /\/.*\/.*\// and $string !~ /\/.*\/.*\/.*\// )
Другие вопросы по тегам