Regex: Согласование путем исключения, без надежды – возможно ли это?

В некоторых вариантах регулярных выражений [отрицательные] утверждения нулевой ширины (look-ahead / look-behind) не поддерживаются.

Это делает чрезвычайно трудным (невозможным?) Утверждать исключение. Например, «каждая строка, которая не имеет« foo »на ней», вот так:

^((?!foo).)*$ 

Можно ли добиться такого же результата без использования внешнего вида (сложность и производительность на данный момент отложены)?

ОБНОВЛЕНИЕ: он не работает «с двумя ff до оо», как отметил @Ciantic в комментариях.


 ^(f(o[^o]|[^o])|[^f])*$ 

ПРИМЕЧАНИЕ. Гораздо проще просто отменить совпадение на стороне клиента, а не использовать указанное выше регулярное выражение.

Регулярное выражение предполагает, что каждая строка заканчивается символом новой строки, если она не видна в регулярных выражениях C ++ и grep.

Примеры программ в Perl, Python, C ++ и grep дают одинаковый результат.

  • Perl

     #!/usr/bin/perl -wn print if /^(f(o[^o]|[^o])|[^f])*$/; 
  • питон

     #!/usr/bin/env python import fileinput, re, sys from itertools import ifilter re_not_foo = re.compile(r"^(f(o[^o]|[^o])|[^f])*$") for line in ifilter(re_not_foo.match, fileinput.input()): sys.stdout.write(line) 
  • C ++

     #include  #include  #include  int main() { boost::regex re("^(f(o([^o]|$)|([^o]|$))|[^f])*$"); //NOTE: "|$"s are there due to `getline()` strips newline char std::string line; while (std::getline(std::cin, line)) if (boost::regex_match(line, re)) std::cout << line << std::endl; } 
  • Grep

     $ grep "^\(f\(o\([^o]\|$\)\|\([^o]\|$\)\)\|[^f]\)*$" in.txt 

Пример файла:

 foo 'foo' abdfoode abdfode abdfde abcde f fo foo fooo ofooa ofo ofoo 

Вывод:

 abdfode abdfde abcde f fo ofo 

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

Конечно, я не уверен, есть ли какие-либо вкусы, которые позволяют группировать атомы, но не искать, но вопрос спросил, возможно ли в регулярном выражении исключить исключение без искажений, и это технически возможно:

 \A(?:$|[^f]++|f++(?:[^o]|$)|(?:f++o)*+(?:[^o]|$))*\Z 

Объяснение:

 \A #Start of string (?: #Non-capturing group $ #Consume end-of-line. We're not in foo-mode. |[^f]++ #Consume every non-'f'. We're not in foo-mode. |f++(?:[^o]|$) #Enter foo-mode with an 'f'. Consume all 'f's, but only exit foo-mode if 'o' is not the next character. Thus, 'f' is valid but 'fo' is invalid. |(?:f++o)*+(?:[^o]|$) #Enter foo-mode with an 'f'. Consume all 'f's, followed by a single 'o'. Repeat, since '(f+o)*' by itself cannot contain 'foo'. Only exit foo-mode if 'o' is not the next character following (f+o). Thus, 'fo' is valid but 'foo' is invalid. )* #Repeat the non-capturing group \Z #End of string. Note that this regex only works in flavours that can match $\Z 

Если по какой-либо причине вы можете использовать атомарную группировку, но не обладающие квантификаторами и не искать, вы можете использовать:

 \A(?:$|(?>[^f]+)|(?>f+)(?:[^o]|$)|(?>(?:(?>f+)o)*)(?:[^o]|$))*\Z 

Как отмечают другие, хотя, вероятно, более практично просто отрицать матч другими способами.

Обычно вы можете искать foo и инвертировать результат соответствия регулярного выражения из кода клиента.

Для простого примера предположим, что вы хотите проверить, что строка содержит только определенные символы.

Вы могли бы написать следующее:

^[A-Za-z0-9.$-]*$

и принять true результат как действительный, или вот так:

[^A-Za-z0-9.$-]

и принять false результат как действительный.

Конечно, это не всегда вариант: иногда вам просто нужно поместить выражение в файл конфигурации или передать его в другую программу, например. Но стоит вспомнить. Ваша конкретная проблема, например, выражение намного проще, если вы можете использовать это отрицание.

Я наткнулся на этот вопрос, ища свое решение для исключения регулярных выражений, где я пытаюсь исключить последовательность внутри своего регулярного выражения.

Моя первоначальная реакция на эту ситуацию: например, «каждая строка, которая не имеет« foo »на ней», просто заключалась в использовании опции -v для инвертирования соответствия в grep.

 grep -v foo 

это возвращает все строки в файле, который не соответствует ‘foo’

Это так просто, у меня сильное чувство, что я просто неправильно понял ваш вопрос ….

  • Regex: игнорировать чувствительность к регистру
  • RegEx: присвоение значений между кавычками
  • Регулярное выражение для запрещения более 1 штриха последовательно
  • Не удается избежать обратного слэша с помощью регулярного выражения?
  • Regex: все, кроме
  • Сопоставление всех слов, кроме одного
  • Как я могу распознать злое регулярное выражение?
  • Регулярное выражение для поиска текста между второй и третьей косой чертой
  • регулярное выражение для букв, цифр и - _
  • Регулярное выражение для пар синтаксического анализа имени
  • Regex: Определите, могут ли два регулярных выражения совпадать для одного входа?
  • Interesting Posts

    Критерии для гибернации для дат

    Макет для планшетов в Android

    Как подключить файловую систему NTFS, разрешая всем пользователям полный доступ?

    Каков наилучший способ реализации «таймера»?

    Используйте xcodebuild (Xcode 8) и автоматическое подписание в средах CI (Travis / Jenkins)

    Соединение не может быть выполнено, потому что целевая машина активно отказалась от него 127.0.0.1:3446

    Объявления Mopub не показываются

    Более безопасная, но простая в использовании и гибкая альтернатива C ++ для s ++ ()

    Как распечатать UTF-8 из консольного приложения c ++ в Windows

    ASP.NET MVC – Медленная начальная загрузка

    Утилита для блокировки положения окна и размера окон в Windows 7

    В чем разница между persist () и merge () в Hibernate?

    Как перезагрузить файл свойств весной 4 с помощью аннотаций?

    несколько операторов обновления mongo в одном заявлении?

    Является ли размер C “int” 2 байта или 4 байта?

    Давайте будем гением компьютера.