Regex: khớp mọi thứ nhưng mẫu cụ thể


310

Tôi cần một regex có thể khớp mọi thứ trừ một chuỗi bắt đầu bằng một mẫu cụ thể (cụ thể index.phpvà những gì tiếp theo, như index.php?id=2342343)


Và mô hình cụ thể nào bạn muốn không phù hợp?
Dominic Rodger

2
Có một lý do tại sao bạn không thể phù hợp với mô hình của bạn và không làm điều gì đó nếu chuỗi phù hợp với điều đó?
Thomas Owens


@ThomasOwens: Nó phụ thuộc. Nó phụ thuộc vào phần nào của biểu thức sẽ bị phủ định. Nếu toàn bộ biểu thức bị phủ định, thì bạn đã có một điểm. Ví dụ: nếu bạn muốn mã hóa "nếu chuỗi không chứa 'Bruce' dưới dạng chuỗi con, thì hãy làm gì đó", bạn sử dụng rõ ràng / Bruce /, và đặt phủ định vào câu lệnh if, bên ngoài regex . Nhưng nó có thể là bạn muốn phủ nhận một số biểu hiện phụ. Giả sử, bạn đang tìm kiếm một cái gì đó như tên họ, trong đó tên đầu tiên là Bruce và họ là tất cả mọi thứ ngoại trừ XYZ, trong đó XYZ là tên cuối cùng của một người nổi tiếng được gọi là Bruce.
mathheadinclouds

Câu trả lời:


250

Không phải là một chuyên gia regrec, nhưng tôi nghĩ rằng bạn có thể sử dụng một cái nhìn tiêu cực ngay từ đầu, ví dụ như ^(?!foo).*$không nên khớp với bất cứ điều gì bắt đầu với foo.


7
Với grep sử dụng -P để kích hoạt lookahead.
Seppo Enarvi

Nếu không khớp "foo" hoặc "bar" là hành vi mong muốn của bạn, hãy kiểm tra câu trả lời sau: stackoverflow.com/a/2404330/874824
dave_k_smith

15
Câu trả lời này là sai, một bài kiểm tra nhanh cho thấy rằng. Tôi nghĩ ý của bạn là ^((?!foo).)*$( stackoverflow.com/a/406408/3944381 )
gilad mayani

4
Xin vui lòng giải thích các biểu tượng bạn đã sử dụng và tại sao bạn sử dụng chúng?
rotimi-best

339

Regex: khớp mọi thứ nhưng :

Lưu ý demo : dòng mới \nđược sử dụng bên trong các lớp ký tự bị phủ định trong các bản demo để tránh tràn khớp với (các) dòng lân cận. Chúng không cần thiết khi kiểm tra các chuỗi riêng lẻ.

Lưu ý về neo : Trong nhiều ngôn ngữ, sử dụng \Ađể xác định bắt đầu chuỗi rõ ràng và \z(trong Python \Z, trong JavaScript, $OK) để xác định phần cuối của chuỗi.

Ghi chú dấu chấm : Trong nhiều hương vị (nhưng không phải POSIX, TRE, TCL), .phù hợp với bất kỳ char nào ngoài char mới . Đảm bảo bạn sử dụng công cụ sửa đổi DOTALL tương ứng ( /strong PCRE / Boost / .NET / Python / Java và /mtrong Ruby) .để khớp với bất kỳ char nào kể cả dòng mới.

Ghi chú dấu gạch chéo ngược : Trong các ngôn ngữ mà bạn phải khai báo các mẫu có chuỗi C cho phép thoát chuỗi (như \nđối với dòng mới), bạn cần tăng gấp đôi dấu gạch chéo ngược thoát các ký tự đặc biệt để công cụ có thể coi chúng là ký tự chữ (ví dụ: trong Java, world\.sẽ khai báo là "world\\.", hoặc sử dụng một lớp ký tự "world[.]":). Sử dụng chuỗi ký tự thô (Python r'\bworld\b'), chuỗi ký tự C # verbatim hoặc chuỗi ký tự @"world\."gạch chéo / ký hiệu regex như thế nào /world\./.


Tuyệt vời viết lên! Đối với trường hợp "một chuỗi (không) bằng một số chuỗi", với ví dụ về ^(?!foo$), tại sao ký hiệu đô la phải nằm trong dấu ngoặc đơn để biểu thức hoạt động? Tôi đã mong đợi ^(?!foo)$để đưa ra kết quả tương tự, nhưng nó không.
Cấp Humphries

3
@GrantHumphries: Khi mỏ $neo nằm trong diện mạo, nó là một phần của điều kiện, một phần của khẳng định độ rộng bằng không đó . Nếu nó ở bên ngoài, như trong ^(?!foo)$, nó sẽ là một phần của mô hình tiêu thụ yêu cầu kết thúc chuỗi ngay sau khi bắt đầu chuỗi, làm cho giao diện phủ định không liên quan vì nó sẽ luôn trả về đúng (không thể có bất kỳ văn bản nào sau khi kết thúc chuỗi , hãy để một mình foo). Vì vậy, ^(?!foo$)khớp bắt đầu của một chuỗi không foođược theo sau với chuỗi kết thúc. ^(?!foo)$phù hợp với một chuỗi trống.
Wiktor Stribiż

@ robot.txt Hãy xóa những bình luận này. Bạn đang hỏi một câu hỏi XY. Các lớp ký tự có nghĩa là khớp với các ký tự đơn, không có cách nào để định nghĩa một chuỗi ký tự với chúng. Có lẽ bạn chỉ nên tìm chuỗi con giữa bắt đầu chuỗi và lần xuất hiện đầu tiên của cothoặc lan, và xóa kết quả khớp, như thế nào regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Wiktor Stribiżew

Kính gửi Wiktor. Bạn đã đóng câu hỏi của tôi tuy nhiên câu trả lời được liên kết của bạn không thành công. Tôi đã cập nhật stackoverflow.com/questions/60004380/
MonsterMMORPG

Ví dụ: câu trả lời được liên kết của bạn không thành công trong ví dụ này "ing gói <! - và trang web <! - asdasasdas -> trình chỉnh sửa hiện sử dụng -> Lorem Ipsum"
MonsterMMORPG

259

Bạn có thể đặt một ^phần đầu của một bộ ký tự để khớp với bất cứ thứ gì trừ những ký tự đó.

[^=]*

sẽ phù hợp với tất cả mọi thứ nhưng =


55
Điều đó đúng, nhưng nó chỉ xử lý một ký tự một lần. Nếu bạn muốn loại trừ một chuỗi gồm hai hoặc nhiều ký tự, bạn phải sử dụng giao diện phủ định như những người phản hồi khác đã nói.
Alan Moore

giải pháp hoàn hảo tu loại bỏ bất kỳ nhân vật không mong muốn nhưng những người trong mô hình. cảm ơn
Xác nhận

@Alan, "... bạn phải sử dụng một cái nhìn tiêu cực ..." là không chính xác, nhưng chúng tôi không nên quá khó khăn với bạn vì Wiktor đã không đăng câu trả lời của mình - điều này cho thấy tại sao - cho đến năm 2016.
Cary Swoveland

6

Chỉ cần phù hợp /^index\.php/sau đó từ chối bất cứ điều gì phù hợp với nó.


Có lẽ viết str !~ /\Aindex\.php/.
Cary Swoveland

6

Trong trăn:

>>> import re
>>> p='^(?!index\.php\?[0-9]+).*$'
>>> s1='index.php?12345'
>>> re.match(p,s1)
>>> s2='index.html?12345'
>>> re.match(p,s2)
<_sre.SRE_Match object at 0xb7d65fa8>

3
Điều đó sẽ từ chối "index_php" hoặc "index # php".

1

Tôi cần một thể regex để phù hợp với tất cả mọi thứ nhưng ngoại trừ một chuỗi bắt đầu với index.php một mô hình cụ thể (đặc biệt là index.php và những gì sau, giống như index.php? Id = 2.342.343)

Sử dụng phương pháp Exec

    let match,
        arr = [],
        myRe = /([\s\S]+?)(?:index\.php\?id.+)/g;

    var str = 'http://regular-viragenia/index.php?id=2342343';

    while ((match = myRe.exec(str)) != null) {
         arr.push(match[1]);
    } 
    
    console.log(arr);

var myRe = /([\s\S]+?)(?:index\.php\?id=.+)/g;
var str = 'http://regular-viragenia/index.php?id=2342343';
var matches_array = myRe.exec(str);
console.log(matches_array[1]);

HOẶC MATCH KHÁC

let match,
            arr = [],
            myRe = /index.php\?id=((?:(?!index)[\s\S])*)/g;

        var str = 'http://regular-viragenia/index.php?id=2342343index.php?id=111index.php?id=222';

        while ((match = myRe.exec(str)) != null) {
             arr.push(match[1]);
        } 

        console.log(arr);


-13

Còn về việc không sử dụng regex:

// In PHP
0 !== strpos($string, 'index.php')

11
OP đặc biệt yêu cầu một regex ... Tôi không chắc điều này có ích! (Anh ta có thể được sử dụng greptrên dòng lệnh, ví dụ, hoặc Perl / Python / bất kỳ ngôn ngữ nào khác, hoặc một "Execute regex này cho mỗi dòng" lệnh trong một trình soạn thảo văn bản, vv ...)
rinogo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.