结合正则表达式模式以匹配分隔字符串

时间:2016-09-28 06:19:27

标签: regex sed substring grouping

背景

希望仅在由美元符号(从不跨越行)划分的文本中用美元符号替换句点。例如:

Names: $annie.bettie.cindy.dannie.ellie$. Only $a$ names. $a.b.c.d.e.f$.

问题

following regex几乎可行,但过于简单:

/([[:alnum:]])\.([[:alnum:]])/g

如果分隔符($)之外存在匹配项,那么将会替换太多匹配项。

以下正则表达式:

/\$.*?\$/g

Matches and groups分隔的字符串:

  

姓名: $ annie.bettie.cindy.dannie.ellie $ 。只有 $ a $ 名称。的 $ $ a.b.c.d.e.f

问题

如何组合两个正则表达式,以便可以用另一个字符串替换句点?例如:

Names: $annie.bettie.cindy.dannie.ellie$. Only $a$ names. $a.b.c.d.e.f$.

最终将成为:

Names: `r v$annie$bettie$cindy$dannie$ellie`. Only `r v$a` names. `r v$a$b$c$d$e$f`.

我遇到的麻烦是匹配分隔点。

正则表达式将从运行bash的终端传送到sed。

2 个答案:

答案 0 :(得分:1)

这可能适合你(GNU sed):

sed -r ':a;s/^(([^$]*\$[^$.]*\$)*[^$]*\$[^$.]*)\./\1\n/;ta;s/(\$[^$]*)\$/`r v\1`/g;y/\n/$/' file

用换行符替换组内的所有句点。插入组前缀和后缀文字,然后将换行符转换为美元。

答案 1 :(得分:1)

$ cat ip.txt 
Names: $annie.bettie.cindy.dannie.ellie$. Only $a$ names. $a.b.c.d.e.f$.

$ perl -pe '
BEGIN
{
    sub f
    {
        $a = $_[0] =~ tr/./$/r;
        $a =~ s/^/`r v/;
        $a =~ s/.$/`/;
        return $a;
    }
}
s/\$.*?\$/f($&)/ge
' ip.txt
Names: `r v$annie$bettie$cindy$dannie$ellie`. Only `r v$a` names. `r v$a$b$c$d$e$f`.
  • 子例程f$sometext$字符串执行必要的转换 - 首先音译.$,然后在开头添加一些字符串,最后删除要替换的最后一个字符要求的格式
    • 子程序放在BEGIN块中,该块在逐行处理输入文件之前执行
  • s/\$.*?\$/f($&)/ge将提取$sometext$模式并传递给f子例程。 Perl知道称它为e旗帜
  • -p开关表示输入行在所有命令后打印