Regex 用于变量替换的perl正则表达式

Regex 用于变量替换的perl正则表达式,regex,perl,Regex,Perl,我想替换以“#”标记并以点或非字母数字字符结尾的变量。 示例:变量#名称应替换为“Peter” 这可以工作,但是否可以将其合并为一个表达式?您可以使用 s/#name(?|\.()|(\W))/Peter$1/i 详细信息 #name-匹配文本子字符串 (?|\.()|(\W))-匹配两个备选方案之一: \.()-一个点,然后将一个空字符串捕获到$1 |-或 (\W)-捕获到$1中的任何非单词字符 因此,匹配后,$1占位符要么为空,要么包含除点以外的任何非单词字符。有几种可能的方法 s

我想替换以“#”标记并以点或非字母数字字符结尾的变量。 示例:变量#名称应替换为“Peter”

这可以工作,但是否可以将其合并为一个表达式?

您可以使用

s/#name(?|\.()|(\W))/Peter$1/i
详细信息

  • #name
    -匹配文本子字符串
  • (?|\.()|(\W))
    -匹配两个备选方案之一:
    • \.()
      -一个点,然后将一个空字符串捕获到
      $1
    • |
      -或
    • (\W)
      -捕获到
      $1
      中的任何非单词字符

因此,匹配后,
$1
占位符要么为空,要么包含除点以外的任何非单词字符。

有几种可能的方法

s/#name(\W)/"Peter" . ($1 eq "." ? "" : $1)/e
在这里,我们使用
/e
将替换部分转换为表达式,因此我们可以检查
$1
并动态选择替换字符串

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

这里我们使用
(?|
重置分支之间捕获组的编号,因此
\.()
([^.\w])
都设置
$1
。如果匹配了
$1
将成为空字符串;否则,它将包含匹配的字符。

您可以使用文字点或字边界作为终止符

像这样

s/#name(?:\.|\b)/Peter/i
这是一个完整的程序,它可以复制您的问题中显示的所需输出

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;
}
输出
@melpomene我们可以使用
s/#name(?124;\.()|(\ W))/Peter$1/i
来解决这个问题,这是将要使用的一系列替换中的第一个,所以
(?|\.()|(\W))
很好。@Borodin是的,但我觉得
[^.\W]
更明确和健壮。例如,如果有人将我的正则表达式嵌入到一个更大的上下文中,它就不可能以意外的方式开始匹配。如果你真的在做Perl变量替换,那么你可能想看看是什么使Perl自己的运行时双引号字符串内插代码可用。这样,您可以使用
$s='abc$name def'
$s='abc${name}def'
,然后在设置
$name='Peter'
后进行插值。哦,太好了。你甚至可以做
#name\b\。?
@melpomene:我没发现。我从
\name(?:\.\124;(?=\ W))
开始反向工作,但只做了一半@梅尔波梅:
s/#name\b\?/Peter/
很好!
s/#name(?:\.|\b)/Peter/i
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;
}
abc#name.def => abcPeterdef
abc#namedef  => abc#namedef
abc#name-def => abcPeter-def