简体   繁体   中英

perl regex for variable substitution

I want to substitute variables marked by a "#" and terminated by a dot or a non-alphanumeric character. Example: Variable #name should be substituted be "Peter"

abc#name.def => abcPeterdef
abc#namedef  => abc#namedef
abc#name-def => abcPeter-def

So if the variable is terminated with a dot, it is replaced and the dot removed. Is it terminated by any non-alphanum character, it is replaced also.

I use the following:

s/#name\./Peter/i
s/#name(\W)/Peter$1/i

This works but is it possible to merge it into one expression?

There are several possible approaches.

s/#name(\W)/"Peter" . ($1 eq "." ? "" : $1)/e

Here we use /e to turn the replacement part into an expression, so we can inspect $1 and choose the replacement string dynamically.

s/#name(?|\.()|([^.\w]))/Peter$1/

Here we use (?| ) to reset the numbering of capture groups between branches, so both \\.() and ([^.\\w]) set $1 . If a . is matched, $1 becomes the empty string; otherwise it contains the matched character.

You may use

s/#name(?|\.()|(\W))/Peter$1/i

Details

  • #name - matches the literal substring
  • (?|\\.()|(\\W)) - a branch reset group matching either of the two alternatives:
    • \\.() - a dot and then captures an empty string into $1
    • | - or
    • (\\W) - any non-word char captured into $1 .

So, upon a match, $1 placeholder is either empty or contains any non-word char other than a dot.

You can do this by using either a literal dot or a word boundary for the terminator

Like this

s/#name(?:\.|\b)/Peter/i

Here's a complete program that reproduces the required output shown in your question

use strict;
use warnings 'all';

for my $s ( 'abc#name.def', 'abc#namedef', 'abc#name-def' ) {

    ( my $s2 = $s ) =~ s/#name(?:\.|\b)/Peter/i;

    printf "%-12s => %-s\n", $s, $s2;
}

output

abc#name.def => abcPeterdef
abc#namedef  => abc#namedef
abc#name-def => abcPeter-def

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