2009-08-18 9 views
3

私はいくつかのテキストの "間"をつかむいくつかのコードを持っています。 、具体的には、foo $somewordと次のfoo $somewordの間です。なぜ私のPerl正規表現は無限ループを引き起こしますか?

しかし、最初の "between"に詰まって何らかの形で内部文字列の位置が増えない場合はどうなりますか?

入力データは、ここに改行が付いたテキストファイルです。それらはむしろ無関係ですが、印刷が容易になります。

my $component = qr'foo (\w+?)\s*?{'; 

while($text =~ /$component/sg) 
{ 
    push @baz, $1; #grab the $someword 
} 

my $list = join("|", @baz); 
my $re = qr/$list/; #create a list of $somewords 

#Try to grab everything between the foo $somewords; 
# or if there's no $foo someword, grab what's left. 

while($text=~/($re)(.+?)foo ($re|\z|\Z)/ms) 
#if I take out s, it doesn't repeat, but nothing gets grabbed. 
{ 
# print pos($text), "\n"; #this is undef...that's a clue I'm certain. 
    print $1, ":", $2; #prints the someword and what was grabbed. 
    print "\n", '-' x 20, "\n"; 
} 
+2

あなたは「/したくありませんg "修飾子も2番目のループにありますか? – jrockway

+0

\ zと\ Zは必要ありません。\ Zには\ zが含まれています。\ z –

+0

私はテキストを歩いていて、配列をつかんでいません(これは/ gが返すものです)。ただし、/ gは最終出力の問題には影響しません。私はもう試した。 :-) –

答えて

4

更新:'foo'あなたが抽出したいテキスト内で発生に対処するためのつ以上更新:

use strict; 
use warnings; 

use File::Slurp; 

my $text = read_file \*DATA; 

my $marker = 'foo'; 
my $marker_re = qr/$marker\s+\w+\s*?{/; 

while ($text =~ /$marker_re(.+?)($marker_re|\Z)/gs) { 
    print "---\n$1\n"; 
    pos $text -= length $2; 
} 

__DATA__ 
foo one { 
one1 
one2 
one3 

foo two 
{ two1 two2 
two3 two4 } 

that was the second one 

foo three { 3 
foo 3 foo 3 
foo 3 
foo foo 

foo four{} 

出力:

 
--- 

one1 
one2 
one3 


--- 
two1 two2 
two3 two4 } 

that was the second one 


--- 
3 
foo 3 foo 3 
foo 3 
foo foo 


--- 
} 
+0

について、はい。私は{そして、次のfooの前にすべてを探しています。 –

+0

それは動作します。 pos $ text - = 3が指定されていない場合は、最初と最後を返します。 私はあなたのソリューションがなぜ働いていたのか、私の問題は何かを混乱させています。思考? –

+0

fooがあれば '(?:foo | \ Z)'は 'foo'の長さだけ' pos $ text'を進めます。したがって、 'pos $ text'が現在の位置の3文字前の次の' foo 'の前の位置にリセットされない限り、次の 'foo'の後に次のマッチが始まります。すでにストリングの終わりに当たっていれば、これは問題ではありません。 –

関連する問題