简体   繁体   中英

Conditional in perl regex replacement

I'm trying to return different replacement results with a perl regex one-liner if it matches a group. So far I've got this:

echo abcd |  perl -pe "s/(ab)(cd)?/defined($2)?\1\2:''/e"

But I get

Backslash found where operator expected at -e line 1, near "1\"
(Missing operator before \?)
syntax error at -e line 1, near "1\"
Execution of -e aborted due to compilation errors.

If the input is abcd I want to get abcd out, if it's ab I want to get an empty string. Where am I going wrong here?

You used regex atoms \\1 and \\2 (match what the first or second capture captured) outside of a regex pattern. You meant to use $1 and $2 (as you did in another spot).

Further more, dollar signs inside double-quoted strings have meaning to your shell. It's best to use single quotes around your program [1] .

echo abcd | perl -pe's/(ab)(cd)?/defined($2)?$1.$2:""/e'

Simpler:

echo abcd | perl -pe's/(ab(cd)?)/defined($2)?$1:""/e'

Simpler:

echo abcd | perl -pe's/ab(?!cd)//'

  1. Either avoid single-quotes in your program [2] , or use '\\'' to "escape" them.
  2. You can usually use q{} instead of single-quotes. You can also switch to using double-quotes. Inside of double-quotes, you can use \\x27 for an apostrophe.

Why torture yourself, just use a branch reset.

Find (?|(abcd)|ab())
Replace $1

And a couple of even better ways

Find abcd(*SKIP)(*FAIL)|ab
Replace ""

Find (?:abcd)*\\Kab
Replace ""

These use regex wisely.
There is really no need nowadays to have to use the eval form
of the regex substitution construct s///e in conjunction with defined().
This is especially true when using the perl command line.

Good luck...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM