2012-08-11 37 views
12

Tôi đã poring over perldoc perlre cũng như Regular Expressions Cookbook và các câu hỏi liên quan trên Stack Overflow và tôi dường như không thể tìm thấy những gì dường như là một biểu thức rất hữu ích: làm thế nào để tôi biết số lượng phù hợp hiện tại?Có cách nào để đánh giá số lần biểu thức chính quy Perl đã khớp không?

Có biểu hiện cho phù hợp với nhóm khép kín qua ($^N), nội dung của trận đấu 3 (\g{3} nếu tôi hiểu các tài liệu một cách chính xác), $', $&$`. Nhưng có vẻ như không phải là một biến tôi có thể sử dụng mà chỉ đơn giản là cho tôi biết số lượng của trận đấu hiện tại là gì.

Có thực sự bị thiếu không? Nếu vậy, có bất kỳ lý do kỹ thuật giải thích tại sao nó là một điều khó khăn để thực hiện, hoặc tôi chỉ không đọc perldoc cẩn thận đủ?

Xin lưu ý rằng tôi quan tâm đến biến tích hợp, NOT cách giải quyết như sử dụng (${$count++}).

Đối với ngữ cảnh, tôi cố gắng tạo biểu thức chính quy chỉ khớp với một số trường hợp khớp (ví dụ: khớp với tất cả các lần xuất hiện của ký tự "E" nhưng KHÔNG khớp với các lần xuất hiện 3, 7 và 10 trong đó 3, 7 và 10 chỉ đơn giản là số trong một mảng). Tôi gặp phải vấn đề này khi cố gắng xây dựng một câu trả lời thành ngữ hơn cho this SO question.

Tôi muốn tránh đánh giá các regex làm chuỗi để chèn 3, 7 và 10 vào chính regex.

+0

Xin lưu ý rằng tôi cần số lần so khớp, không phải # trong số các nhóm đã chụp. – DVK

+0

'Xin lưu ý rằng tôi quan tâm đến biến tích hợp': Nếu nó không nằm trong perloc perlvar, nó có tồn tại không? Tôi đã giả định rằng perlvar chứa các biến tích hợp * tất cả * perl. – TLP

+1

Không có biến nào như vậy. perlvar không ghi lại tất cả các biến tích hợp - ví dụ '@ ISA' không xuất hiện - nhưng mọi thứ đều được ghi lại ở đâu đó. Perl có xu hướng không có chức năng ẩn. Bạn có thể đưa ra một ví dụ về vấn đề bạn đang cố gắng giải quyết tốt hơn so với tham chiếu bạn đưa ra không? – Borodin

Trả lời

5

Tôi đã chơi trò chơi này một chút. Một lần nữa, tôi biết rằng đây không thực sự là những gì bạn đang tìm kiếm, nhưng tôi không nghĩ rằng nó tồn tại theo cách bạn muốn.

Tôi đã có hai suy nghĩ. Đầu tiên, với split sử dụng chế độ lưu giữ dấu phân cách, bạn nhận được các bit kẽ làm các phần tử được đánh số lẻ trong danh sách đầu ra. Với danh sách từ split, bạn đếm mà phù hợp bạn đang ở trên và đặt nó trở lại với nhau như thế nào bạn thích:

use v5.14; 

$_ = 'ab1cdef2gh3ij4k5lmn6op7qr8stu9vw10xyz'; 

my @bits = split /(\d+)/; # separator retention mode 

my @skips = qw(3 7 10); 
my $s; 
while(my($index, $value) = each @bits) { 
    # shift indices to match number (index = 2 n - 1) 
    if($index % 2 and ! (($index + 1)/2 ~~ @skips)) { 
     $s .= '^'; 
     } 
    else { 
     $s .= $value; 
     } 
    } 

tôi nhận được:

ab^cdef^gh3ij^k^lmn^op7qr^stu^vw10xyz 

tôi nghĩ rằng tôi thực sự thích split câu trả lời của tôi cho đến khi tôi có ý nghĩ thứ hai. state có hoạt động thay thế không?Dường như nó:

use v5.14; 
$_ = 'ab1cdef2gh3ij4k5lmn6op7qr8stu9vw10xyz'; 
my @skips = qw(3 7 10); 

s/(\d+)/ 
    state $n = 0; 
    $n++; 
    $n ~~ @skips ? $1 : '$' 
    /eg; 

say; 

này mang lại cho tôi:

ab$cdef$gh3ij$k$lmn$op7qr$stu$vw10xyz 

Tôi không nghĩ rằng bạn có thể nhận được đơn giản hơn nhiều hơn thế, thậm chí nếu điều đó biến ma thuật tồn tại.

Tôi đã có suy nghĩ thứ ba mà tôi không thử. Tôi tự hỏi nếu state hoạt động bên trong xác nhận mã. Nó có thể, nhưng sau đó tôi sẽ phải tìm ra cách sử dụng một trong những người để làm cho một trận đấu thất bại, mà thực sự có nghĩa là nó phải bỏ qua các bit mà có thể đã xuất hiện. Điều đó có vẻ thực sự phức tạp, đó có lẽ là những gì Borodin gây áp lực cho bạn để hiển thị ngay cả trong giả mã.

6

Tôi hoàn toàn bỏ qua tiện ích thực sự hoặc sự khôn ngoan khi sử dụng tính năng này cho câu hỏi khác.

Tôi nghĩ @- hoặc @+ có thể làm những gì bạn muốn vì họ giữ offsets trong những trận đấu được đánh số, nhưng có vẻ như động cơ regex đã biết gì chỉ số cuối cùng sẽ là:

use v5.14; 

use Data::Printer; 

$_ = 'abc123abc345abc765abc987abc123'; 

my @matches = m/ 
    ([0-9]+) 
    (?{ 
     print 'Matched \$' . $#+ . " group with $^N\n"; 
     say p(@+); 
    }) 
    .*? 
    ([0-9]+) 
    (?{ 
     print 'Matched \$' . $#+ . " group with $^N\n"; 
     say p(@+); 
    }) 
    /x; 

say "Matches: @matches"; 

này mang lại cho chuỗi hiển thị chỉ mục cuối cùng là 2 mặc dù nó chưa khớp với $2.

Matched \$2 group with 123 
[ 
    [0] 6, 
    [1] 6, 
    [2] undef 
] 
Matched \$2 group with 345 
[ 
    [0] 12, 
    [1] 6, 
    [2] 12 
] 
Matches: 123 345 

Lưu ý rằng lần đầu tiên xung quanh, $+[2] là không chính xác, do đó chưa được điền đầy đủ. Bạn có thể có thể làm điều gì đó với điều đó, nhưng tôi nghĩ rằng đó có thể là đi từ tinh thần của câu hỏi của bạn. Nếu bạn đã thực sự ưa thích, bạn có thể tạo ra một vô hướng gắn có giá trị của chỉ số được xác định cuối cùng trong @+, tôi đoán.

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