1

使用 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

4 回答 4

4

您正在寻找的可能是一种匹配两个引号之间所有内容的方法。这可以通过使用负字符类来完成(即 /"[^"]*"/)

所以这可能会起作用:

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

但总的来说,我不建议使用正则表达式来处理 xml。它通常很脆弱,如果您的输入变化最少,它通常会损坏。例如,如果它开始使用单引号,因为它突然必须在内容中包含双引号。

于 2012-09-17T11:43:21.323 回答
3

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

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

  1. 在你的字符串中过度转义
  2. 未能使用qr//创建正则表达式(避免完全转义)
  3. /i和选项看起来像是在/g不了解它们的作用的情况下被粘贴了
  4. anifelse具有相同内容的
  5. 缩进不一致
  6. 标量值的不必要引用
  7. empty_it不是一个很好的函数名

我已经修复了我可以在这里修复的部分:

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;
    }
}
于 2012-09-17T12:02:59.230 回答
2

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

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

$twig对象是在keep_spaces启用该选项的情况下创建的。这会保留所有空白 PCDATA,从而保留原始文件的格式和缩进

解析数据后,调用get_xpath查找具有包含至少一个空白字符sentence的属性的所有元素。singing(请注意,这是一种非标准的 XPath 语言特有的XML::Twig

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

请注意,属性为的其他sentence元素输出不变,因为它与搜索不匹配singingNOSPACESget_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>
于 2012-09-17T13:45:43.433 回答
1

您可以指定 char 的反义词。

my $find = '<sentence="[^"]*"';
my $replace = '<sentence=""';
s/$find/$replace/g;
于 2012-09-17T11:46:17.747 回答