2008-12-08 12 views
9

Tôi có một chuỗi từ mà tôi muốn trích xuất một từ duy nhất, nhưng với một số nối vào nó, mà có thể khác nhau trong mỗi dòng:Làm cách nào để tìm chuỗi con trong chuỗi bằng Perl?

This is string1 this is string 
This is string11 
This is string6 and it is in this line 

Tôi muốn phân tích tập tin này và nhận được các giá trị của "stringXXX", bắt đầu từ 0 đến 100

# suppose ABC.txt contains the above lines 
FH1 = open "Abc.txt"; 
@abcFile = <FH1>; 

foreach $line(@abcFile) { 
    if ($pattern =~ s/string.(d{0}d{100}); 
     print $pattern; 

các bản in trên toàn bộ dòng, tôi muốn để có được chỉ stringXXX

Trả lời

13

bạn cần phải nắm bắt nó:

while ($pattern =~/(string(100|\d{1,2}))/g) { 
    print $1; 
} 

Giải thích:

  • chụp ngoặc gì trong chúng thành $ 1. Nếu bạn có nhiều tập hợp parens, số 1 sẽ được ghi lại thành $ 1, số thứ 2 thành $ 2, v.v. Trong trường hợp này $ 2 sẽ có số thực.
  • \ d {1,2} chụp từ 1 đến 3 chữ số, cho phép bạn chụp từ 0 đến 99. 100 bổ sung ở đó cho phép bạn chụp 100 rõ ràng vì đó là số có 3 chữ số bạn muốn khớp.

chỉnh sửa: cố định thứ tự của các số được chụp.

+0

cảm ơn đã giúp :-) – gagneet

+0

nếu // -> trong khi // g – jfs

+0

Cảm ơn @ J.F. Tôi đã cập nhật câu trả lời –

-2

Chỉ cần thay đổi in $ pattern để in $ &, đã được chụp.

+0

Vấn đề là việc chụp được thực hiện sai. –

+0

Ngoài ra, '$ &' có tác động hiệu suất xấu đối với toàn bộ hệ thống của bạn. Xem http://search.cpan.org/perldoc?Devel::SawAmpersand – mpeters

+0

0. Vâng, regex đã sai nhưng sử dụng $ & là mã ngắn nhất để in kết quả chính xác. 1. đây không phải là mã thư viện, tác động hiệu suất cũng giống như sử dụng $ 1. 2. toàn cầu PL_sawampersand hack là một vấn đề thực hiện nội bộ perl và nên được cố định trong perl. – ididak

5

Abc.pl:

#!/usr/bin/perl -w  
while(<>) { 
    while (/(string(\d{1,3}))/g) {  
    print "$1\n" if $2 <= 100; 
    } 
} 

Ví dụ:

$ cat Abc.txt 
This is string1 this is string 
This is string11 
This is string6 and it is in this line 
string1 asdfa string2 
string101 string3 string100 string1000 
string9999 string001 string0001 

$ perl Abc.pl Abc.txt 
string1 
string11 
string6 
string1 
string2 
string3 
string100 
string100 
string001 
string000 

$ perl -nE"say $1 while /(string(?:100|\d{1,2}(?!\d)))/g" Abc.txt 
string1 
string11 
string6 
string1 
string2 
string3 
string100 
string100 

Lưu ý sự khác biệt giữa kết quả đầu ra. Điều gì là thích hợp hơn phụ thuộc vào nhu cầu của bạn.

-1

Đừng chỉ định quá mức. Để nắm bắt phần số, chỉ cần sử dụng (\ d +). Điều này sẽ nắm bắt một số chiều dài bất kỳ, vì vậy mà một số ngày khi những con khỉ đang cung cấp cho bạn với tập tin này quyết định mở rộng phạm vi của họ lên đến 999, bạn sẽ được bảo hiểm. Nó cũng ít suy nghĩ, cả bây giờ khi bạn đang viết, và sau đó khi bạn đang duy trì.

Hãy nghiêm khắc về những gì bạn phát ra, nhưng tự do trong những gì bạn chấp nhận.

+0

nó thực sự phụ thuộc vào spec bạn đang đưa ra. Nếu bạn đang viết một kịch bản throwaway để nắm bắt chỉ những con số này, bạn không muốn sử dụng (\ d +) –

+0

Tôi không thể tìm ra nó, Nathan ... tại sao không? Nếu tôi chỉ viết một kịch bản ngắn, tôi không muốn đầu tư thêm thời gian để làm cho regex phức tạp hơn thế. – skiphoppy