One Face One Face - 7 months ago 8
Perl Question

Why do I have to escape `]` in my regex?

I got an error when I ran the following:

perl -ne 'print unless (/[A-G][\d|\s|m|#|$]/)' file


The error:

Unmatched [ in regex; marked by <-- HERE in m/[A-G][ <-- HERE \d|\s|m|#|5.022001/ at -e line 1, <> line 1


I resolved the error by escaping the
]
at the end of the line:

perl -ne 'print unless (/[A-G][\d|\s|m|#|$\]/)' file


Why did I have to escape the last
]
? What prevents the bracket from being matched?

I have noticed this is not the case for all
[]
matches. Is this a special case?

Answer
perl -ne 'print unless (/[A-G][\d|\s|m|#|$]/)' file

Apparently the $] is being interpreted by Perl as the $] variable, which contains the current version of Perl.

But that regular expression doesn't make much sense anyway. In this part of it:

[\d|\s|m|#|$]

the text between the [ and ] is a sequence of characters or ranges of characters, and the expression matches any one of those characters. Adding a backslash:

[\d|\s|m|#|\$]

means it's going to match a single backslash, 'd', 's', m', '$', '|', or '$' character. (I'm not 100% certain about the details.) You probably want:

(\d|\s|m|#|$)

You can tweak that if you don't want the matching text stored in $1:

(?:\d|\s|m|#|$)

but that's probably not worthwhile for this one-liner.

Also, the outer parentheses aren't necessary. Putting this all together, what you probably want is:

perl -ne 'print unless /[A-G](\d|\s|m|#|$)/' file