2010-12-09 3 views
1

Regexp::Common qw/URI /とPergeのRegexに関する2つの質問があります。Perlでは、カッコで囲まれたURLを正しく抽出するにはどうすればよいですか?

私はRegexp::Common qw/URI/を使用して、文字列のURIを解析して削除します。しかし、URIがかっこで囲まれている場合はエラーが発生します。例えば

:それはURI、アプリのクラッシュを解析しようとすると、(http://www.example.com)

エラーが「)」によって引き起こされる、とされます。だから、私は2つの修正を考えた:

  • は、単純な(または私はそう思った)を行い、括弧と)文字の間に空白
  • Regexp::Common qw/URI/を書き込み、その修正プログラムを実装する機能を持っています。

私のコードでは、Regexを実装しようとしましたが、アプリケーションがフリーズしました。私が試したコードはこれです:

use strict; 

use Regexp::Common qw/URI/; 
my $str = "Hello!!, I love (http://www.example.com)"; 
while ($str =~ m/\)/){ 
       $str =~ s/\)/ \)/; 
     } 
my ($uri) = $str =~ /$RE{URI}{-keep}/; 
print "$uri\n"; 
print $str; 

私が欲しいの出力は次のようになります。(http://www.example.com)

私はわからないんだけど、私は問題はところで$str =~ s/\)/ \)/;

であると思い、 Regexp :: Common qw/URI /に関する質問があります。私はそれが最後のコンポーネントである場合、URIを削除(して保存)したいhttp://www.example.com aasdfasdfasdf

asfasdfasdf http://www.example.com

    1. ablalbalblalblalbal:私は2つの文字列型を持っています。そして、もしそうでなければ、それをテキストから取り除かずに保存してください。

  • +0

    投稿の書式設定のヒントを読む必要があります。あなたの投稿にURLの束を含めることができるようにライブリンクを入力する必要はありません。また、コードに '
    'を挿入する必要はありません。 –

    答えて

    0
    my $str = "Hello!!, I love (GOOGLE)"; 
    while ($str =~ m/)/){ 
        $str =~ s/)/)/; 
    } 
    

    この時点で、プログラムは無限ループに入ります。理由を調べるには、ループのたびに$ strの値を出力してみてください。

    my $str = "Hello!!, I love (GOOGLE)"; 
    while ($str =~ m/)/){ 
        $str =~ s/)/)/; 
        print $str, "\n"; 
    } 
    

    "Hello !!、I love(GOOGLE)"を初めて印刷します。その後、whileループ条件が再度評価されます。あなたの文字列はまだ正規表現と一致しています(それでも閉じ括弧が含まれています)ので、置換えが再度実行され、今度は "Hello !!、I love(GOOGLE)"という2つのスペースが印刷されます。

    そして、それが続きます。ループのたびに別のスペースが追加されますが、まだ閉じ括弧があるたびに別の置換が実行されます。

    私が見ることができる最も簡単な解決策は、(\ Sを使用して)空白以外の文字が前に付いている場合にのみ、閉じ括弧に一致させることです。

    my $str = "Hello!!, I love (GOOGLE)"; 
    while ($str =~ m/\S)/){ 
        $str =~ s/)/)/; 
        print $str, "\n"; 
    } 
    

    この場合、ループは1回だけ実行されます。

    2

    s///演算子を正しく使用できる一致を最初にテストする必要はありません。文字列が検索パターンと一致しない場合、何も実行されません。

    #!/usr/bin/perl 
    
    use strict; use warnings; 
    
    my $str = "Hello!!, I love (GOOGLE)"; 
    $str =~ s/\)/)/g; 
    
    print "$str\n"; 
    

    テキストで正しくURLを検出する一般的な問題は、エラーが発生しやすいです。例えば、Jeff's thoughts on thisを参照してください。

    0

    検索にカッコを入れるだけではどうですか? URLは常に括弧された場合は、このようなもの、そして:

    #!/usr/bin/perl 
    use warnings; 
    use strict; 
    use Regexp::Common qw/URI/; 
    
    my $str = "Hello!!, I love (http://www.google.com)"; 
    my ($uri) = $str =~/\(($RE{URI}) \) /x; 
    print "$uri\n"; 
    

    正規表現から正規表現::一般的には長い正規表現の一部として使用することができ、それは自分自身で使用する必要はありません。また、私は正規表現で 'x'修飾子を使用して空白を許可し、何が起こっているのかをより明確に見ることができます。バックスラッシュを含む括弧は一致する文字として扱われ、一致しないものは(おそらく{-keep} - 以前はそれを使っていませんでした)。

    また、のようなもので、ブラケットをオプションにできます。それは2つの試合変数、未定義の1になるでしょうが

    / (?: \(($RE{URI}) \) | ($RE{URI}))/
    

    - ので、以下のようなものが必要とされるであろう:

    my $uri = $1 || $2 || die "Didn't match a URL!"; 
    

    をおそらくこれを行うための良い方法があります。また、カッコにマッチすることに悩まされていない場合でも、最初の正規表現で大カッコをオプション( '?')にすることができます。

    行の最後に一致するURLのみに関する2番目の質問に答えるには、行の先頭または末尾に一致するようにするRegexのアンカーを見てください:^と$(または\ Aと\ Zあなたが好きなら)。例えば行末のURLとの一致:

    /$RE{URI}\Z/ 
    
    関連する問題