Regex: cocokkan semuanya kecuali pola tertentu

310

Saya membutuhkan regex yang dapat mencocokkan semuanya kecuali string yang dimulai dengan pola tertentu (khusus index.phpdan apa yang mengikuti, seperti index.php?id=2342343)

pistacchio
sumber
Dan pola spesifik apa yang Anda inginkan agar tidak cocok?
Dominic Rodger
2
Apakah ada alasan mengapa Anda tidak dapat mencocokkan dengan pola Anda dan tidak melakukan sesuatu jika string cocok dengan itu?
Thomas Owens
@ThomasOwens: Tergantung. Itu tergantung pada bagian mana dari ekspresi harus dinegasikan. Jika seluruh ekspresi harus dinegasikan, maka Anda mendapat poin. Misalnya, jika Anda ingin membuat kode "jika string tidak mengandung 'Bruce' sebagai substring, maka lakukan sesuatu", Anda akan menggunakan plain / Bruce /, dan memasukkan negasi ke dalam pernyataan if, di luar regex . Tapi bisa jadi Anda ingin meniadakan beberapa subekspresi. Katakanlah, Anda mencari sesuatu seperti nama belakang nama belakang, di mana nama depan adalah Bruce, dan nama belakang adalah segalanya kecuali XYZ, di mana XYZ adalah nama terakhir dari beberapa selebriti bernama Bruce.
mathheadinclouds

Jawaban:

250

Bukan ahli regexp, tapi saya pikir Anda bisa menggunakan lookahead negatif dari awal, misalnya ^(?!foo).*$tidak harus cocok dengan apa pun yang dimulai dengan foo.

Cat Plus Plus
sumber
7
Dengan grep gunakan -P untuk mengaktifkan lookahead.
Seppo Enarvi
Jika tidak cocok dengan "foo" atau "bar" adalah perilaku yang Anda inginkan, periksa jawaban ini: stackoverflow.com/a/2404330/874824
dave_k_smith
15
Jawaban ini salah, tes cepat menunjukkan itu. Saya pikir yang Anda maksud adalah ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
gilad mayani
4
Bisakah Anda menjelaskan simbol yang Anda gunakan dan mengapa Anda menggunakannya?
rotimi-best
339

Regex: cocokkan semua kecuali :

Catatan demo : baris baru \ndigunakan di dalam kelas karakter yang dinegasikan dalam demo untuk menghindari kecocokan pencocokan dengan baris tetangga. Mereka tidak perlu saat menguji string individu.

Catatan jangkar : Dalam banyak bahasa, gunakan \Auntuk mendefinisikan awal string yang jelas, dan \z(dalam Python \Z, dalam JavaScript, $adalah OK) untuk menentukan bagian paling akhir dari string.

Dot note : Dalam banyak rasa (tapi bukan POSIX, TRE, TCL), .cocok dengan char apa pun kecuali char baris baru . Pastikan Anda menggunakan pengubah DOTALL yang sesuai ( /sdi PCRE / Boost / .NET / Python / Java dan /mdi Ruby) .agar sesuai dengan karakter apa pun termasuk baris baru.

Catatan\n garis miring terbalik : Dalam bahasa di mana Anda harus mendeklarasikan pola dengan string C yang memungkinkan urutan pelarian (seperti untuk baris baru), Anda perlu menggandakan garis miring terbalik yang keluar dari karakter khusus sehingga mesin dapat memperlakukan mereka sebagai karakter literal (misalnya di Jawa, world\.akan menjadi dinyatakan sebagai "world\\.", atau menggunakan kelas karakter:) "world[.]". Gunakan literal string mentah (Python r'\bworld\b'), literal string C # verbatim @"world\.", atau string slashy / regex notasi literal seperti /world\./.

Wiktor Stribiżew
sumber
Tulis hebat! Untuk kasus "string (tidak) sama dengan beberapa string", dengan contoh ^(?!foo$), mengapa tanda dolar harus berada dalam tanda kurung agar ekspresi tersebut berfungsi? Saya mengharapkan ^(?!foo)$untuk memberikan hasil yang sama, tetapi tidak.
Grant Humphries
3
@GrantHumphries: Ketika $jangkar berada di dalam lookahead, itu adalah bagian dari kondisi, bagian dari pernyataan lebar nol itu . Jika berada di luar, seperti di ^(?!foo)$, itu akan menjadi bagian dari pola konsumsi yang membutuhkan akhir string tepat setelah awal string, membuat tampilan negatif tidak relevan karena akan selalu kembali benar (tidak ada teks setelah akhir string , apalagi foo). Jadi, ^(?!foo$)kecocokan mulai dari string yang tidak diikuti dengan fooyang diikuti dengan akhir string. ^(?!foo)$cocok dengan string kosong.
Wiktor Stribiżew
@ robots.txt Harap hapus komentar ini. Anda mengajukan pertanyaan XY. Kelas karakter dimaksudkan untuk mencocokkan karakter tunggal, tidak ada cara untuk menentukan urutan karakter. Anda mungkin harus menemukan substring antara awal string dan kemunculan pertama cotatau lan, dan menghapus kecocokan, seperti regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Wiktor Stribiżew
Wiktor yang terhormat. Anda telah menutup pertanyaan saya namun jawaban yang ditautkan gagal. Saya telah memperbarui pertanyaan saya stackoverflow.com/questions/60004380/…
MonsterMMORPG
Misalnya jawaban tertaut Anda gagal pada contoh ini "paket <! - dan halaman web <! - asdasasdas -> editor sekarang menggunakan -> Lorem Ipsum"
MonsterMMORPG
259

Anda dapat menempatkan a ^di awal set karakter untuk mencocokkan apa pun kecuali karakter tersebut.

[^=]*

akan cocok dengan segalanya kecuali =

Firsh - LetsWP.io
sumber
55
Itu benar, tetapi hanya memproses satu karakter pada satu waktu. Jika Anda ingin mengecualikan urutan dua karakter atau lebih, Anda harus menggunakan lookahead negatif seperti kata responden lainnya.
Alan Moore
solusi sempurna dan menghapus karakter yang tidak diinginkan selain yang ada dalam pola terima kasih
Sirmyself
@Lan, "... kamu harus menggunakan lookahead negatif ..." salah, tapi kami tidak boleh terlalu keras padamu karena Wiktor tidak memposting jawabannya - yang menunjukkan mengapa - sampai 2016.
Cary Swoveland
6

Cocokkan saja /^index\.php/lalu tolak apa pun yang cocok dengannya.


sumber
Mungkin ditulis str !~ /\Aindex\.php/.
Cary Swoveland
6

Dengan python:

>>> 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>
AJ.
sumber
3
Itu akan menolak "index_php" atau "index # php".
1

Aku butuh mampu regex untuk mencocokkan segalanya tapi kecuali sebuah string yang dimulai dengan index.php pola tertentu (khusus index.php dan apa yang berikut, seperti index.php? Id = 2.342.343)

Gunakan metode 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]);

ATAU PERTANDINGAN LAINNYA

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);

Юрий Светлов
sumber
-13

Bagaimana kalau tidak menggunakan regex:

// In PHP
0 !== strpos($string, 'index.php')
Percutio
sumber
11
OP secara khusus meminta regex ... Saya tidak yakin ini bisa membantu! (Dia mungkin menggunakan greppada command-line, misalnya, atau Perl / Python / bahasa lain, atau perintah "Jalankan regex ini untuk setiap baris" dalam editor teks, dll ...)
rinogo