Regex: відповідати всім, крім певного шаблону


310

Мені потрібен регулярний вираз, здатний відповідати всьому, окрім рядка, починаючи з певного шаблону (конкретно index.phpі що далі, як index.php?id=2342343)


І з якою конкретною схемою ви не хочете відповідати?
Домінік Роджер

2
Чи є причина, чому ви не можете відповідати шаблону і не робити щось, якщо рядок відповідає цьому?
Томас Оуенс


@ThomasOwens: Це залежить. Це залежить від того, яку частину виразу слід заперечувати. Якщо весь вираз потрібно заперечувати, то ви отримаєте бал. Наприклад, якщо ви хочете зашифрувати "якщо рядок не містить" Bruce "як підрядку, то зробіть щось", ви скористаєтеся просто / Bruce / і введете заперечення в оператор if, поза регексом . Але, можливо, ви хочете заперечити деякий піддекспресія. Скажімо, ви шукаєте щось на кшталт прізвища, де ім’я - Брюс, а прізвище - це все, крім XYZ, де XYZ - прізвище якоїсь знаменитості з назвою Брюс.
mathheadinclouds

Відповіді:


250

Не експерт по регулярному вибору, але я думаю, що ви могли використовувати негативний пошук з самого початку, наприклад, ^(?!foo).*$не повинні відповідати нічого, починаючи з foo.


7
Використовуйте grep -P для включення пошуку.
Seppo Enarvi

Якщо не відповідає «Foo» або «бар» є ваше бажане поведінку, перевірити цей відповідь: stackoverflow.com/a/2404330/874824
dave_k_smith

15
Ця відповідь неправильна, швидкий тест показує, що. Я думаю , що ви мав в виду, ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
Гілад mayani

4
Поясніть, будь ласка, пояснення використаних вами символів та чому ви їх використовували?
rotimi-best

339

Regex: відповідає всім, окрім :

Демо примітка : новий рядок \nвикористовується всередині заперечених класів символів у демонстраціях, щоб уникнути переповнення відповідності до сусідніх рядків. Вони не потрібні при тестуванні окремих рядків.

Примітка прив’язки : У багатьох мовах використовуйте \Aдля визначення однозначного початку рядка та\z (у Python, це \Zв JavaScript, $це нормально) для визначення самого кінця рядка.

Примітка до точки : у багатьох ароматах (але не POSIX, TRE, TCL) .відповідає будь-якому знаку, а не знаку нового рядка . Переконайтеся, що ви використовуєте відповідний модифікатор DOTALL ( /sу PCRE / Boost / .NET / Python / Java та/m Ruby), .щоб відповідати будь-якому знаку, включаючи новий рядок.

Примітка зворотного косого ряду : мовами, де потрібно оголошувати візерунки з рядками C, що дозволяють виконувати послідовності втечі (наприклад, \nдля нового рядка), потрібно подвоїти косоокі риси, уникаючи спеціальних символів, щоб двигун міг трактувати їх як буквальні символи (наприклад, на Java, world\.буде оголошено як "world\\."або використовувати клас символів:) "world[.]". Використовуйте необроблені рядкові літерали (Python r'\bworld\b'), @"world\."дослідницькі рядки C # дословно або строгі рядки / регекс-літеральні позначення, як-от /world\./.


Чудово запишіть! Для випадку "рядок (не), який дорівнює деякій рядку", на прикладі ^(?!foo$), чому так, що знак долара повинен бути в дужках, щоб вираз працював? Я розраховував ^(?!foo)$дати ті ж результати, але це не так.
Грант Хамфріс

3
@GrantHumphries: Коли $якір знаходиться всередині штриху, він є частиною умови, частиною цього твердження нульової ширини . Якщо він був зовні, як у ^(?!foo)$, це буде частиною споживаючого шаблону, що вимагає закінчення рядка одразу після початку рядка, що робить негативний lookahead нерелевантним, оскільки він завжди повернеться true (текст не може бути після закінчення рядка , не кажучи вже про foo). Отже, ^(?!foo$)починається збіг початку рядка, який не дотримується fooтого, який слід з кінцем рядка. ^(?!foo)$відповідає порожньому рядку.
Wiktor Stribiżew

@ robots.txt Видаліть ці коментарі. Ви задаєте питання XY. Класи символів призначені для узгодження одиничних символів, немає способу визначити послідовність знаків з ними. Ймовірно, ви повинні просто знайти підрядку між початком рядка і першим появою cotабо lan, і видалити відповідність, як regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Wiktor Stribiżew

Шановний Вікторе. Ви закрили моє запитання, проте ваша відповідна відповідь не вдається. Я оновив своє запитання stackoverflow.com/questions/60004380/…
MonsterMMORPG

Наприклад, ваша відповідна відповідь не в цьому прикладі "ing пакети <! - і веб-сторінка <! - asdasasdas -> редактори зараз використовують -> Lorem Ipsum"
MonsterMMORPG

259

Ви можете поставити ^на початку набір символів, щоб відповідати будь-якому, крім цих символів.

[^=]*

відповідатиме всім, але =


55
Це правда, але вона обробляє лише один символ за один раз. Якщо ви хочете виключити послідовність з двох або більше символів, вам доведеться використовувати негативний пошук, як сказали інші відповіді.
Алан Мур

ідеальне рішення, щоб усунути будь-який небажаний персонаж, окрім тих, що є у малюнку. спасибі
Sirmyself

@Alan, "... ви повинні використовувати негативний пошук ..." є невірним, але ми не повинні бути надто жорсткими до вас, оскільки Wiktor не опублікував свою відповідь - що показує, чому - до 2016 року
Cary Swoveland

6

Просто збіг, /^index\.php/тоді відкиньте все, що відповідає.


Можливо, написано str !~ /\Aindex\.php/.
Cary Swoveland

6

У пітоні:

>>> 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
Це відхилить "index_php" або "index # php".

1

Мені потрібно регулярний вираз в стані відповідати всі , але за винятком того, в рядок , починаючи з index.php певного шаблону ( в Зокрема , index.php і що слід, як index.php? ID = 2342343)

Використовуйте метод 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]);

АБО ІНШИЙ МАТЧ

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

Як щодо використання не регулярного вираження:

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

11
ОП спеціально просив регулярний вираз ... Я не впевнений, що це допомагає! (Він може використовуватись grepу командному рядку, наприклад, або Perl / Python / будь-якою іншою мовою, або командою "Виконати цей регулярний вираз для кожного рядка" у текстовому редакторі тощо).
rinogo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.