2009-08-18 37 views
3

我有一些代碼抓住一些文本之間的「之間」; 具體而言,在foo $someword和接下來的foo $someword之間。爲什麼我的Perl正則表達式導致無限循環?

然而,它會卡在第一個「之間」,不知怎的,內部字符串位置不會增加。

輸入數據是一個帶有換行符的文本文件:它們非常不相關,但使打印更容易。

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「修飾符在第二個循環中也是? – jrockway 2009-08-18 22:01:39

+0

\ z和\ Z沒有必要,\ Z包含\ z – 2009-08-18 22:11:24

+0

我正在遍歷文本,而不是抓取數組(這是什麼/ g會返回)。但是,/ g不會影響最終輸出問題。我試過了。 :-) – 2009-08-18 22:11:43

回答

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之前的所有內容。 – 2009-08-18 22:18:51

+0

這有效。 沒有pos $ text - = 3,它返回第一個和最後一個。 恐怕我很困惑*爲什麼*您的解決方案工作和我的錯在哪裏。思考? – 2009-08-18 22:33:32

+0

如果有foo,尋找'(?:foo | \ Z)'將'pos $ text'提前'foo'的長度。因此,下一場比賽在下一個'foo'之後開始,除非將'pos $ text'重置爲當前位置之前三個字符之前的下一個'foo'之前的位置。如果你已經擊中了字符串的末尾,這並不重要。 – 2009-08-18 22:42:26

相關問題