2016-09-28 65 views
1

背景

展望更换只能在文字美元符号是由美元符号(从来没有跨越线)界定时期。例如:结合正则表达式模式来匹配组分隔字符串内

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

也许[该SO线索](http://stackoverflow.com/questions/25241413/pass-the-匹配值函数和替换值与返回值)可以抛出一些光。 –

+1

你能解释你的预期产出吗?问题声明说你需要在'$ sometext $'模式中用'$'替换'。',特别是我没有在模式结束时得到'''''''''' – Sundeep

+0

@Sundeep:目标是创建一个正则表达式,将简单的[Pandoc](http://pandoc.org/)YAML变量引用转换为更强大的内联[knitr](http://yihui.name/knitr/)表达式。 –

回答

1

这可能为你工作(GNU SED):

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

由换行符替换组内的所有时段。插入组前缀和后缀字面量,然后将换行符转换为美元。

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开关装置输入行之后的所有获取打印命令