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

あなたが探しているのは、おそらく2つの引用符の間のすべてのコンテンツを一致させる方法です。これは、負の文字クラス(つまり、/ "[^"] * "/)を使用して実行できます。

したがって、これはおそらく機能します:

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. ifおよびelse同じ内容を持つ
  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 が保持されるため、元のファイルの書式設定とインデントが維持されます。

データが解析されると、 への呼び出しにより、少なくとも 1 つの空白文字を含む属性を持つget_xpathすべての要素が検出されます。(これは に固有の非標準 XPath 言語であることに注意してください)sentencesingingXML::Twig

ループはsinging、これらすべての要素の属性を null 文字列に設定し$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 に答える