3

I have try few method to match a word that contain exact 3 times slash but cannot work. Below are the example

@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";
    }

Few macthing i try but none of them work

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

Any other way i can match this type of string and print the string?

Sundar R
  • 13,776
  • 6
  • 49
  • 76
Tim
  • 214
  • 1
  • 12

4 Answers4

8

Match a / globally and compare the number of matches with 3

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

where the =()= operator is a play on context, forcing list context on its right side but returning the number of elements of that list when scalar context is provided on its left side.

If you are uncomfortable with such a syntax stretch then assign to an array

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

where the subsequent comparison evaluates it in the scalar context.

You are trying to match three consecutive / and your string doesn't have that.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • Hi @zdim , if i want to print the string that match, how should i do? – Tim May 25 '18 at 06:53
  • 1
    @Tim, Your code already does that. `for (@array) { say if ( () = m{/}g ) == 3; }` or `for my $string (@array) { say $string if ( () = $string =~ m{/}g ) == 3; }` – ikegami May 25 '18 at 07:00
3

The pattern you need (with whitespace added) is

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

or

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

Your second attempt was close, but using ^ without \z made it so you checked for string starting with your pattern.


Solutions:

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

or

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

or

say for grep { tr{/}{} == 3 } @array;
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

You need to match

  • a slash
  • surrounded by some non-slashes (^(?:[^\/]*)
  • repeating the match exactly three times
  • and enclosing the whole triple in start of line and and of line anchors:
$string =~ /^(?:[^\/]*\/[^\/]*){3}$/;
Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40
-1
if ( $string =~ /\/.*\/.*\// and $string !~ /\/.*\/.*\/.*\// )
  • it will give you exactly what you want. First part matches with line which has at least 3 slash and second part removes those lines which match with four matches. – sandeep singh Jun 01 '18 at 15:20