Подтвердить что ты не робот

Как превратить любое регулярное выражение в дополнение к себе без сложного редактирования вручную?

Ниже приведены псевдо-примеры, а не реальное регулярное выражение, но все же пример того, что я имею в виду:


.* (anything)

-.* (NOT anything)

[A-Z] (Any letter A to Z, caps only)

-[A-Z] (NOT any letter A to Z, caps only)

EDIT: Изменено в дополнение к дополнению. Здесь, где было сделано изменение: "превратите любое регулярное выражение в дополнение самого себя"

4b9b3361

Ответ 1

Прежде всего, я считаю, что вы имеете в виду дополнение регулярного выражения, а не инверсное. Обратное к регулярному выражению не имеет большого смысла; но если рассматривать как функцию, я полагаю, вы могли бы сказать, что обратный к собору является генератором, который генерирует все соответствующие строки - или что-то. С другой стороны, дополнение языка - это все те строки, которые не находятся на исходном языке.

Затем здесь нужно рассмотреть два вида:

Фундаментально

Дополнение регулярного языка является регулярным. Это означает, что можно создать принимающий DFA для дополнения (и сделать это очень просто, на самом деле: просто поменять не принимающее состояние с набором принимающих состояний). Любой такой DFA может быть выражен как регулярное выражение - так что в принципе вы действительно можете сделать такое регулярное выражение.

В качестве отправной точки см. статью wikipedia на Regular Languages ​​.

Практически

Типичный синтаксис regex, совместимый с perl, используемый в большинстве современных языков в настоящее время, не имеет оператора комплементации. Для полного регулярного выражения вы можете получить что-то подобное, используя отрицательный оператор lookahead: (?!X) будет соответствовать строке точно, когда X не будет. Однако это плохая замена оператора дополнения, поскольку вы не сможете использовать его как часть большого регулярного выражения обычным способом; это регулярное выражение не "потребляет" вход, что означает, что он ведет себя по-разному в сочетании с другими операторами.

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

Несколько по иронии судьбы, практическое воплощение регулярных выражений теоретически более мощное из-за обратных ссылок, но практически менее гибкое, поскольку язык не может легко выразить операции комплемента и пересечения.

Ответ 2

Просто запустите регулярное выражение и логически инвертируйте вывод. Итак, измените:

if(/foo/)

в

if(!/foo/)

Символьные классы могут быть инвертированы с помощью ведущего карат:

[A-Z] → [^ A-Z]

У многих специальных символов также есть инверсии, если вы воспользуетесь спецификатором.

\s whitespace
\S non-whitespace
\w word character
\W non-word-character
\d digit
\D non-digit

Ответ 3

Несколько вариантов:

Сопоставьте строку, состоящую из определенного набора символов: ^[a-z]*$

Сопоставьте строку, состоящую из всего, но не определенного набора символов: ^[^a-z]*$

Обратите внимание, что есть несколько ярлыков:

  • \w: любой буквенно-цифровой символ (включая _),
  • \w: любой не-буквенно-цифровой символ;
  • \s: любой символ пробела,
  • \s: любой символ без пробелов,
  • \d: любая цифра,
  • \d: любая цифра.

Это может стать довольно сложным, например, если вы хотите...

  • только не буквы: [\d_\W], или
  • только буквы: [^\d_\W] (то есть "не цифра, а не _, а не не буквенно-цифровой символ)

Сопоставьте строку, содержащую подстроку: ^.*substring.*$

Сопоставьте строку, не содержащую подстроку: ^(?:(?!substring).)*$

Обратите внимание, как мы должны проверять каждую позицию в строке для "отсутствия присутствия" подстроки. Вы также можете подставить любое регулярное выражение для substring для соответствия строкам, которые содержат или не содержат определенного подрежима.


Сопоставьте что-нибудь: .* (если вы хотите также совместить новые строки, вам нужно будет установить соответствующую опцию вашего языка программирования, например, re.DOTALL в Python)

Сопоставьте что-нибудь, если вы не знаете, как установить эту опцию: [\s\S]*

Никогда не соглашайтесь ни с чем (по какой-либо причине):

  • $^ (то есть совпадение конца строки перед началом строки),
  • \b\B (соответствует позиции, где есть одновременно граница слова, а не граница слова) или
  • (?!) (соответствует позиции, где невозможно совместить пустую строку).

Ответ 4

Используя негативный прогноз, вы сможете обрабатывать большинство основных случаев

/(?!(OriginalRegex)).*?/

Ответ 5

Первый пример не имеет смысла, но для второго вы можете использовать отрицание символа класса:

[a-z] --> [^a-z]

Ответ 6

Я пытаюсь понять определение обратного для регулярного выражения.

match (input, regular_expression) = {match1, match2,..., matchN}

Как бы обратная работа? Если это что-то вроде

match (input, inverse_regular_expression) = {imatch1, imatch2,..., imatchN}

Если да, то какова связь между первым набором результатов и вторым? Если нет, то что это такое?