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

310

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

pistacchio
источник
И какой конкретный шаблон вы хотите не соответствовать?
Доминик Роджер
2
Есть ли причина, по которой вы не можете сопоставить свой шаблон и ничего не делать, если строка соответствует этому?
Томас Оуэнс
@ThomasOwens: Это зависит. Это зависит от того, какая часть выражения должна быть отрицана. Если все выражение должно быть отрицано, тогда вы получите точку. Например, если вы хотите закодировать «если строка не содержит« Брюса »в качестве подстроки, а затем сделать что-то», вы просто используете / Bruce / и вставляете отрицание в оператор if вне регулярного выражения , Но может случиться так, что вы захотите отрицать некоторые подвыражения. Скажем, вы ищете что-то вроде имени, фамилии, где имя - Брюс, а фамилия - все, кроме XYZ, где XYZ - фамилия некой знаменитости по имени Брюс.
Математические облака

Ответы:

250

Не эксперт по регулярным выражениям, но я думаю, что вы могли бы использовать отрицательный прогноз с самого начала, например, ^(?!foo).*$не должен совпадать с чем-либо, начиная с foo.

Cat Plus Plus
источник
7
С grep используйте -P для включения просмотра.
Сеппо Энарви
Если ваше поведение не соответствует «foo» или «bar», проверьте этот ответ: stackoverflow.com/a/2404330/874824
dave_k_smith
15
Этот ответ неверен, быстрый тест показывает это. Я думаю, что вы имели в виду ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
Gilad Mayani
4
Пожалуйста, не могли бы вы объяснить символы, которые вы использовали, и почему вы их использовали?
Ротими-
339

Regex: соответствует всем, кроме :

Примечание к демонстрации : \nсимвол новой строки используется в классах отрицательных символов в демонстрациях, чтобы избежать переполнения совпадений для соседних строк. Они не нужны при тестировании отдельных строк.

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

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

Примечание\n обратной косой черты : В языках, где вы должны объявлять шаблоны со строками C, допускающие escape-последовательности (например, для новой строки), вам необходимо удвоить обратную косую черту, избегая специальных символов, чтобы механизм мог обрабатывать их как буквенные символы (например, в Java, world\.будет объявлен как "world\\."или используйте класс символов:) "world[.]". Использование сырья строковых литералов (Python r'\bworld\b'), C # СТЕНОГРАФИЧЕСКИХ строковые литералы @"world\.", или slashy строка / регулярное выражение буквальной нотации как /world\./.

Виктор Стрибьев
источник
Отлично, пиши! Для случая «строка (не), равная некоторой строке», на примере ^(?!foo$), почему знак доллара должен быть в скобках, чтобы выражение работало? Я ожидал ^(?!foo)$дать такие же результаты, но это не так.
Грант Хамфрис
3
@GrantHumphries: когда $якорь находится внутри прогнозной точки, он является частью условия, частью этого утверждения нулевой ширины . Если бы он был снаружи, как, например, в ^(?!foo)$, он будет частью потребляющего шаблона, требующего конца строки сразу после начала строки, что делает отрицательный взгляд неуместным, поскольку он всегда будет возвращать true (после конца строки не может быть текста) не говоря уже foo). Таким образом, ^(?!foo$)сопоставляется начало строки, за которой не следует foo, за которой следует конец строки. ^(?!foo)$соответствует пустой строке.
Wiktor Stribiżew
@ robots.txt Пожалуйста, удалите эти комментарии. Вы задаете вопрос XY. Классы персонажей предназначены для соответствия одиночным символам, нет возможности определить последовательность символов с ними. Вероятно, вам следует просто найти подстроку между началом строки и первым появлением cotили lanи удалить совпадение, например regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Виктор Стрибьев,
Уважаемый Виктор. Вы закрыли мой вопрос, однако ваш связанный ответ не удался. Я обновил свой вопрос stackoverflow.com/questions/60004380/…
MonsterMMORPG
Например, ваш связанный ответ терпит неудачу в этом примере: «Пакеты ing <! - и редакторы веб-страниц <! - asdasasdas -> теперь используют -> Lorem Ipsum»
MonsterMMORPG
259

Вы можете поместить ^в начало набора символов, чтобы соответствовать чему-либо, кроме этих символов.

[^=]*

будет соответствовать всем, кроме =

Фирш - LetsWP.io
источник
55
Это правда, но он обрабатывает только один символ за раз. Если вы хотите исключить последовательность из двух или более символов, вы должны использовать отрицательный прогноз, как говорили другие респонденты.
Алан Мур
Идеальное решение, чтобы удалить любые нежелательные символы, кроме тех, которые в шаблоне. спасибо
Sirmyself
@ Алан, «... ты должен использовать негативную перспективу ...» - это неправильно, но мы не должны быть слишком жесткими с тобой, потому что Виктор не опубликовал свой ответ - что показывает почему - до 2016 года.
Кэри Свовеланд
6

Просто сопоставьте и /^index\.php/отклоните все, что соответствует.


источник
Возможно написано str !~ /\Aindex\.php/.
Кэри Свовеланд,
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>
AJ.
источник
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')
Percutio
источник
11
ОП специально запросил регулярное выражение ... Я не уверен, что это помогает! (Он может использовать grep, например, в командной строке или Perl / Python / любой другой язык, или команду «Выполнить это регулярное выражение для каждой строки» в текстовом редакторе и т. Д ...)
rinogo