Perl和regex:如何清空包含多个空格的文本行? (空格数可以变化)

时间:2012-09-17 11:32:00

标签: regex perl

使用Perl,我需要清空包含多个空格的字符串

我不能拿出正确的正则表达式

这是我的文字:

<sentence="I am walking on the street and it is raining" >
</sentence>

我想清空此字符串以获取:

<sentence="" >
</sentence>

这是我的代码(它只是替换没有空格的字符串):

sub empty_it {

    print "\nSTART replacing WO info !!!\n";
    my $find    = "\<sentence\=\"\\S*\"";
    my $replace = "\<sentence\=\"\"";
    {  
        local @ARGV = ("$_[0]");
        local $^I = '.baz';
        while ( <> ) {
            if (s/$find/$replace/ig) {
                print;
            }
            else {
                print;
            }
        }
    }
}

4 个答案:

答案 0 :(得分:4)

您正在寻找的可能是匹配两个引号之间所有内容的方法。这可以通过使用否定字符类(即/“[^”] *“/)

来完成

所以这可能有用:

my $find = '<sentence="[^"]*"';

但总的来说,我不建议使用正则表达式来修改xml。它往往是脆弱的,如果你的输入变化最小,往往会破坏。例如,如果它开始使用单引号,因为它突然必须在内容中包含双引号。

答案 1 :(得分:3)

您的直接问题是"\S*""I am walking on the street and it is raining"不匹配,因为\S与单词之间的空格不匹配。一个更好的选择是[^"]+,这将匹配任何不是双引号的东西;但是,如果字符串中允许双引号(如果它们被转义),它仍然有问题。当然,我们需要知道解决该问题的转义机制。

您在代码中还有其他几个问题:

  1. 在你的字符串中过度逃避
  2. 未能使用qr//创建正则表达式(以避免完全转义)
  3. /i/g选项看起来就像粘贴在一起而不了解他们的行为
  4. 具有相同内容的ifelse
  5. 不一致缩进
  6. 不必要引用标量值
  7. empty_it不是一个非常好的功能名称
  8. 我已修复了我可以修复的部分:

    sub empty_it {
        print "\nSTART replacing WO info !!!\n";
        my $find    = qr/<sentence="[^"]+"/;
        my $replace = q/<sentence=""/;
        local $^I   = '.baz';
        local @ARGV = ($_[0]);
        while( <> ) {
            s/$find/$replace/ig;
            print;
        }
    }
    

答案 2 :(得分:2)

最好使用久经考验的XML模块来处理XML数据。此程序使用XML::Twig进行您要求的更改

据我所知,您要检查singing元素的所有sentence属性,如果它们包含空格,则将它们设置为空字符串

创建$twig对象时启用了keep_spaces选项。这保留了所有空白PCDATA,因此保留了原始文件的格式和缩进

解析数据后,对get_xpath的调用会查找具有sentence属性且包含至少一个空白字符的所有singing元素。 (请注意,这是XML::Twig

独有的非标准XPath语言

循环只将singing属性设置为所有这些元素的空字符串,$twig->print输出修改后的数据

请注意,sentence属性为singing的其他NOSPACES元素的输出未更改,因为它与get_xpath搜索

不匹配
use strict;
use warnings;

use XML::Twig;
my $twig = XML::Twig->new(keep_spaces => 1);

$twig->parse(*DATA);

for my $sentence ( $twig->get_xpath('//sentence[@singing =~ /\s/]') ) {
  $sentence->set_att(singing => '');
}
$twig->print;

__DATA__
<root>
  <sentence singing="I am walking on the street and it is raining" >
  </sentence>
  <sentence singing="NOSPACES" >
  </sentence>
</root>

<强>输出

<root>
  <sentence singing="">
  </sentence>
  <sentence singing="NOSPACES">
  </sentence>
</root>

答案 3 :(得分:1)

您可以指定char的反面。

my $find = '<sentence="[^"]*"';
my $replace = '<sentence=""';
s/$find/$replace/g;