Регулярное выражение, которое не содержит определенную строку
У меня есть что-то вроде этого
aabbabcaabda
для выбора минимальной группы, обернутой a У меня есть этот /a([^a]*)a/
, который отлично работает
Но у меня проблема с группами, обернутыми aa, где мне нужно что-то вроде
/aa([^aa]*)aa/
, который не работает, и я не могу использовать первый, например /aa([^a]*)aa/
, потому что он закончится при первом входе a, который я не хочу.
Как правило, есть ли способ, как сказать не содержать строку так же, как
Я могу сказать, что не содержит символ с [^a]
?
Проще говоря, мне нужен aa, за которым следует любой символ, кроме последовательности aa, а затем заканчивается на aa
Ответы
Ответ 1
В общем, больно писать регулярное выражение not, содержащее определенную строку. Мы должны были сделать это для моделей вычислений - вы берете NFA, которую достаточно легко определить, а затем свести к регулярному выражению. Выражение для вещей, не содержащих "кошку", составляло около 80 символов.
Изменить: я только что закончил и да, это:
aa([^a] | a[^a])aa
Здесь - очень краткий учебник. Раньше я нашел несколько отличных, но я больше их не вижу.
Ответ 2
Пользуясь Google, я нашел blogpost от 2007, который дает следующее регулярное выражение, которое соответствует строке, которая не делает содержит определенную подстроку:
^((?!my string).)*$
Он работает следующим образом: он ищет нулевые или более (*) символы (.), которые не начинают (?! - negative lookahead) вашу строку, и в ней оговаривается, что вся строка должна состоять из таких символов (по используя якобы ^ и $). Или иначе:
Вся строка должна состоять из символов, которые не начинаются с заданной строки, а это означает, что строка не содержит заданную подстроку.
Ответ 3
Все, что вам нужно, - это неохотный квантификатор:
regex: /aa.*?aa/
aabbabcaabda => aabbabcaa
aaaaaabda => aaaa
aabbabcaabda => aabbabcaa
aababaaaabdaa => aababaa, aabdaa
Вы также можете использовать отрицательный lookahead, но в этом случае это всего лишь более верный способ выполнить одно и то же. Кроме того, это немного сложнее, чем gpojd сделал это. Смотритель должен применяться в каждой позиции до того, как точка будет иметь возможность использовать следующий символ.
/aa(?:(?!aa).)*aa/
Что касается подхода, предложенного Claudiu и finnw, он будет работать нормально, когда строка дозорного кода имеет всего два символа, но (как признал Клаудиу) это слишком громоздко для более длинных строк.
Ответ 4
/aa([^a]|a[^a])*aa/
Ответ 5
Я не уверен, что это стандартная конструкция, но я думаю, вам стоит взглянуть на "негативный взгляд" (который пишет: "?!", без кавычек).
Это намного проще, чем все ответы в этом потоке, включая принятый.
Пример:
Regex: "^ (?! 123) [0-9] *\w"
Записывает любую строку, начинающуюся цифрами, за которой следуют буквы, ЕСЛИ если "эти цифры" 123.
http://msdn.microsoft.com/en-us/library/az24scfc%28v=vs.110%29.aspx#grouping_constructs
(страница microsoft, но довольно полная) для lookahead/lookbehind
PS: он работает хорошо для меня (.Net). Но если я ошибаюсь, сообщите нам об этом. Я считаю, что эта конструкция очень проста и эффективна, поэтому я удивлен принятым ответом.
Ответ 6
Мне следующий код мне пришлось заменить, добавив GET-параметр ко всем ссылкам на JS файлы EXCEPT one.
<link rel="stylesheet" type="text/css" href="/login/css/ABC.css" />
<script type="text/javascript" language="javascript" src="/localization/DEF.js"></script>
<script type="text/javascript" language="javascript" src="/login/jslib/GHI.js"></script>
<script type="text/javascript" language="javascript" src="/login/jslib/md5.js"></script>
sendRequest('/application/srvc/EXCEPTION.js', handleChallengeResponse, null);
sendRequest('/application/srvc/EXCEPTION.js",handleChallengeResponse, null);
Используется для этого:
(?<!EXCEPTION)(\.js)
Что это значит - это поиск всех вхождений ".js", и если они предшествуют строке "EXCEPTION", отбросьте этот результат из массива результатов. Это называется негативным взглядом. Поскольку я потратил день на выяснение, как это сделать, я думал, что должен поделиться.
Ответ 7
".*[^(\\.inc)]\\.ftl$"
В Java это найдет все файлы, заканчивающиеся на ".ftl", но не заканчивающиеся на ".inc.ftl", что именно то, что я хотел.