仅在perl中的正则表达式匹配中替换字符串

时间:2016-12-18 18:46:34

标签: regex perl

我有一个XML文档,其中包含属性值中的文本。我无法更改XML文件的生成方式,但需要提取属性值而不会丢失\ r \ n。 XML解析器当然会将它们剥离出来。

所以我试图用实体引用替换属性值中的\ r \ n
  我使用perl来做这件事是因为它非贪婪的匹配。但我需要帮助让替换只在比赛中发生。或者我需要一种更简单的方法来执行此操作:)

这是我到目前为止所做的:

perl -i -pe 'BEGIN{undef $/;} s/m_description="(.*?)"/m_description="$1"/smg' tmp.xml

这符合我需要使用的内容:(。*?)。但我不知道扩展该模式以匹配其中的\ r \ n,并在结果中进行替换。如果我知道有多少\ r \ n我有我可以做到,但似乎我需要一个可变数量的捕获组或类似的东西?正则表达式很多,我不明白,似乎应该有一些事情可以做到这一点。

示例:

preceding lines 
stuff m_description="Over
any number
of lines" other stuff
more lines

应该去:

preceding lines 
stuff m_description="Over
any number
of lines" other stuff
more lines

解决方案

感谢Ikegam和ysth提供的解决方案,我使用的是5.14+的解决方案:

perl -i -0777 -pe's/m_description="\K(.*?)(?=")/ $1 =~ s!\n!
!gr =~ s!\r!
!gr /sge' tmp.xml

2 个答案:

答案 0 :(得分:2)

.应该已经匹配\n(因为您指定了/s标志)和\r

要在结果中进行替换,请使用/e

perl -i -0777 -pe's/(?<=m_description=")(.*?)(?=")/ my $replacement=$1; $replacement=~s!\n!&#10;!g; $replacement=~s!\r!&#13;!g; $replacement /sge' tmp.xml

我还将其更改为使用lookbehind / lookahead使代码更简单,并使用-0777将$/设置为slurp模式并删除无用的/m

答案 1 :(得分:0)

好的,所以虽然这看起来像是一个XML问题但事实并非如此。 XML问题是生成它的人。你可能应该给他们一个带有卷的规范副本的prod作为你“修复”这个的第一个停靠点。

但是失败了 - 我会做一个两遍的方法,在那里我阅读文本,找到与描述匹配的所有'blob',然后全部替换它们。

这样的事情:

if (propertyItem.Category == "MyCategory")
{
   propertyItem.Visibility = Visibility.Collapsed;
}