Как сопоставить строку, содержащую точное 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 !~ /\/.*\/.*\/.*\// )