When I run a file which is begin with "#!/usr/bin/perl -w", I get a error: "syntax error at line 153, near "=~ ?""

That is Perl code so the first error message is meaningful.

With delimiters other than // in the match operator you must have the explicit m for it, so

$output_volume =~ m?^([\S]+).mnc?

It is only with // delimiters that the m may be omitted; from Regex Quote-Like Operators (perlop)

If "/" is the delimiter then the initial m is optional.

See perlretut for a tutorial introduction to regex and perlre for reference.

Also note that the particular delimiters of ? trigger specific regex behavior in a special case. This is discussed by the end of the documentation section in perlop linked above.


$output_volume =~ ?^([\S]+).mnc?

This used to be valid perl and thus might appear in old code and instructional material.

From perlop:

In the past, the leading m in m?PATTERN? was optional, but omitting it would produce a deprecation warning. As of v5.22.0, omitting it produces a syntax error. If you encounter this construct in older code, you can just add m.


You already have two answers that explain the problem.

  • ? ... ? is no longer valid syntax for a match operator. You need m? ... ? instead.
  • Until Perl 5.22, your syntax generated a warning. Now it's a fatal error (which is what you are seeing). So I assume you're now running this on a more recent version of Perl.

There are, however, a few other points it is probably worth making.

  1. You say you tried to investigate this by changing the first line of your file from #!/usr/bin/perl -w to #!/bin/bash. I'm not sure how you think this was going to help. This line defines the program that is used to run your code. As you have Perl code, you need to run it with Perl. Trying to run it with bash is very unlikely to be useful.
  2. The m? ... ? (or, formerly, ? ... ?) syntax triggers an obscure and specialised behaviour. It seems to me that this behaviour isn't required in your case, so you can probably change it to the more usual / ... /.
  3. Your regex contains an unescaped dot character. Given that you seem to be extracting the basename from a filename that has an extension, it seems likely that this should be escaped (using \.) so that it matches an actual dot (rather than any character).
  4. If you are using this code to extract a file's basename, then using a regex probably isn't the best approach. Perhaps take a look at File::Basename instead.

Tags:

Perl