2011-09-11 25 views
5

Tôi đang tìm sự xuất hiện của "CCGTCAATTC (A | C) TTT (A | G) AGT" trong một tệp văn bản.Cụm từ thông dụng trong hàm chỉ mục

$text = 'CCGTCAATTC(A|C)TTT(A|G)AGT'; if ($line=~/$text/){ chomp($line); $pos=index($line,$text); }

Searching đang làm việc, nhưng tôi không thể có được vị trí của "văn bản" trong dòng. Có vẻ như chỉ mục không chấp nhận biểu thức chính quy dưới dạng chuỗi con.

Tôi làm cách nào để thực hiện công việc này. Cảm ơn

Trả lời

13

Mảng @- giữ bù trừ vị trí bắt đầu của kết quả phù hợp thành công cuối cùng. Phần tử đầu tiên là phần bù của toàn bộ mẫu phù hợp, và các phần tử tiếp theo là các offset của các mẫu con được lồng vào nhau. Vì vậy, nếu bạn biết có một trận đấu, bạn có thể nhận được bù của nó là $-[0].

1

Bạn không cần sử dụng index chút nào, chỉ là một regex. Phần của $line đến trước khi kết hợp regex của bạn sẽ được lưu trữ trong $` (hoặc $PREMATCH nếu bạn đã chọn sử dụng tiếng Anh;). Bạn có thể lấy chỉ số của trận đấu bằng cách kiểm tra độ dài của $`, và bạn có thể nhận được các trận đấu chính nó từ các $& (hoặc $MATCH) biến:

$text = 'CCGTCAATTC(A|C)TTT(A|G)AGT'; 
if ($line =~ /$text/) { 
    $pos = length($PREMATCH); 
} 

Giả sử bạn muốn nhận được $pos để tiếp tục phù hợp trên còn lại một phần của $line, bạn có thể sử dụng biến số $' (hoặc $POSTMATCH) để lấy phần của $line xuất hiện sau trận đấu.

Xem http://perldoc.perl.org/perlvar.html để biết thông tin chi tiết về các biến đặc biệt này.

+0

Có, tôi có thể làm điều đó. Nhưng khi tôi nắm bắt được vị trí thì tôi sẽ nắm bắt 50 ký tự tiếp theo: 'substr ($ line, $ pos, 50)' – Deep

+0

Bạn có thể khớp với phần còn lại của $ line theo cách bạn đã nói - đó là cách tiếp cận không mong muốn đối với một số lý do? Bạn cũng có thể sử dụng biến $ '(hoặc $ POSTMATCH) để dễ dàng nhận được phần còn lại của dòng $. –

+0

Vui lòng xem câu trả lời đã sửa đổi của tôi; cho tôi biết nếu bạn đang tìm kiếm thứ gì khác. –

1

Dựa trên nhận xét của bạn, có vẻ như những gì bạn đang theo sau khớp với 50 ký tự ngay sau trận đấu. Vì vậy, một giải pháp đơn giản sẽ là:

my ($match) = $line =~ /CCGTCAATTC[AC]TTT[AG]AGT(.{50})/; 

Như bạn thấy, [AG] tương đương với A|G. Nếu bạn muốn so khớp nhiều lần, bạn có thể sử dụng mảng @matches và tùy chọn toàn cầu /g trên regex. Ví dụ.

my @matches = $line =~ /CCGTCAATTC[AC]TTT[AG]AGT(.{50})/g; 

Bạn có thể làm điều này để giữ cho các mô hình phù hợp:

my ($pattern, $match) = $line =~ /(CCGTCAATTC[AC]TTT[AG]AGT)(.{50})/g; 

Hoặc trong một vòng lặp:

while ($line =~ /(CCGTCAATTC[AC]TTT[AG]AGT)(.{50})/g;) { 
    my ($pattern, $match) = ($1, $2); 
} 
+0

Thực ra, tôi cần các ký tự phù hợp để có thể phải ăn gian và thay vì 50 đặt 38 – Deep

+0

Câu hỏi của bạn sẽ đơn giản hơn rất nhiều trả lời nếu bạn đã nói từ đầu những gì bạn muốn? =) Vâng, giả sử bạn biết có bao nhiêu ký tự bạn muốn chụp, tôi nghĩ bạn có thể tìm ra cách khắc phục nó. – TLP

+0

Điều này cũng đã cho tôi một ý tưởng khác, để TLP – Deep

0
while ($line =~ /(CCGTCAATTC[AC]TTT[AG]AGT)(.{50})/g;) { 

tôi thích nó, nhưng không có ; trong while.

Tôi đã gặp khó khăn để tìm kiếm lý do lỗi. T_T.

Các vấn đề liên quan