Có rất nhiều thứ mà cụm từ thông dụng có thể làm - một số trong số đó - như bạn nói - 'ma thuật đen tối'. Nhưng vấn đề cốt lõi là - khá cơ bản, các biểu thức chính quy về lựa chọn văn bản có thể nắm bắt được. Họ không 'làm' so sánh hoặc so sánh đánh giá - chúng có thể khớp hoặc không khớp.
Bạn có thể xem regex đang làm gì, bằng cách bật nó ở chế độ gỡ lỗi. Đối với điều này, tôi sẽ sử dụng perl
bởi vì bạn có thể thiết lập use re 'debug';
':
#!/usr/bin/env perl
use strict;
use warnings;
use re 'debug';
my @matches = "abcemtcmncefmf" =~ m/(cm|c.m|c..m)/;
print join "\n", @matches;
này sẽ in những gì engine regex đang làm như nó đi:
Compiling REx "(cm|c.m|c..m)"
Final program:
1: OPEN1 (3)
3: TRIE-EXACT[c] (19)
<cm> (19)
<c> (9)
9: REG_ANY (10)
10: EXACT <m> (19)
<c> (15)
15: REG_ANY (16)
16: REG_ANY (17)
17: EXACT <m> (19)
19: CLOSE1 (21)
21: END (0)
stclass AHOCORASICK-EXACT[c] minlen 1
Matching REx "(cm|c.m|c..m)" against "abcemtcmncefmf"
Matching stclass AHOCORASICK-EXACT[c] against "abcemtcmncefmf" (14 bytes)
0 <> <abcemtcmnc> | Scanning for legal start char...
2 <ab> <cemtcmncef> | Charid: 1 CP: 63 State: 1, word=0 - legal
3 <abc> <emtcmncefm> | Charid: 0 CP: 65 State: 2, word=2 - fail
3 <abc> <emtcmncefm> | Fail transition to State: 1, word=0 - fail
Matches word #2 at position 2. Trying full pattern...
2 <ab> <cemtcmncef> | 1:OPEN1(3)
2 <ab> <cemtcmncef> | 3:TRIE-EXACT[c](19)
2 <ab> <cemtcmncef> | State: 1 Accepted: N Charid: 1 CP: 63 After State: 2
3 <abc> <emtcmncefm> | State: 2 Accepted: Y Charid: 0 CP: 65 After State: 0
got 2 possible matches
TRIE matched word #2, continuing
3 <abc> <emtcmncefm> | 9: REG_ANY(10)
4 <abce> <mtcmncefmf> | 10: EXACT <m>(19)
5 <abcem> <tcmncefmf> | 19: CLOSE1(21)
5 <abcem> <tcmncefmf> | 21: END(0)
Match successful!
Freeing REx: "(cm|c.m|c..m)"
Hy vọng rằng bạn có thể xem những gì nó làm gì ở đây ?
- làm việc kể từ trái sang phải
- lượt truy cập đầu tiên 'c'
- kiểm tra xem nếu 'cm' matches (thất bại)
- kiểm tra xem nếu 'c.m' phù hợp (thành công).
- thoát ra khỏi đây và trả về số lần truy cập.
Bật g
và bạn làm cho nó hoạt động nhiều lần - Tôi không thể sao chép lại, nhưng lâu hơn rất nhiều.
Trong khi bạn có thể thực hiện rất nhiều thủ thuật thông minh với PCRE, chẳng hạn như nhìn xung quanh, nhìn về phía trước, tham lam/không phù hợp .... khá cơ bản, tại đây, bạn đang cố gắng chọn nhiều kết quả phù hợp và chọn ngắn nhất . Và regex
không thể làm điều đó.
tôi sẽ cung cấp mặc dù - với điều đó cùng perl
, quá trình tìm kiếm ngắn nhất là khá dễ dàng:
use List::Util qw/reduce/;
print reduce { length($a) < length($b) ? $a : $b } @matches;
Tôi nghĩ rằng 'regex' là công cụ sai cho công việc này thực sự. Nó được xây dựng xung quanh các chuỗi phù hợp (và thay thế). Không phân loại logic và so sánh. – Sobrique
Logic bắt giữ của bạn là gì và điểm của '. {0,2}?' Sau 'm' là gì? – anubhava
@Sobrique trên thực tế Tôi không cần một * phân loại logic *, nhưng nếu mỗi mẫu trên nhóm (a | b | c) có thể được kết hợp từng cái một (đầu tiên thử a, nếu thất bại, sau đó thử b, nếu thất bại, sau đó thử c) trên tất cả các chuỗi (cho đến khi kết thúc cho mỗi mẫu mục nhóm) và trả về mẫu đầu tiên, nó sẽ giải quyết mà không cần phân loại bất kỳ thứ gì. Cảm ơn. –