Как совместить "все до этой последовательности символов" в регулярном выражении?
Возьмем это регулярное выражение: /^[^abc]/
. Это будет соответствовать любому одиночному символу в начале строки, кроме a, b или c.
Если вы добавите *
после него - /^[^abc]*/
- регулярное выражение будет продолжать добавлять каждый последующий символ к результату, пока не встретит либо a
, или b
, или c
.
Например, с исходной строкой "qwerty qwerty whatever abc hello"
выражение будет соответствовать "qwerty qwerty wh"
.
Но что, если я хочу, чтобы строка соответствия была "qwerty qwerty whatever "
... Другими словами, как я могу сопоставить все до (но не включая) точную последовательность "abc"
?
Ответы
Ответ 1
Вы не указали, какой аромат регулярного выражения вы используете, но это будет
работать в любом из самых популярных, которые можно считать "полными".
/.+?(?=abc)/
Как это работает
Часть .+?
- это нежелательная версия .+
(одна или несколько
что-нибудь). Когда мы используем .+
, двигатель будет в основном соответствовать всем.
Затем, если в регулярном выражении есть что-то еще, он вернется по шагам
пытаясь соответствовать следующей части. Это поведение жадного,
что означает как можно больше, чтобы удовлетворить.
При использовании .+?
вместо одновременного совпадения и возврата
другие условия (если они есть), двигатель будет соответствовать следующим символам
шаг, пока последующая часть регулярного выражения не будет сопоставлена (опять же, если таковая имеется).
Это un-greedy, что означает соответствие максимально возможного
удовлетворяют условию.
/.+X/ ~ "abcXabcXabcX" /.+/ ~ "abcXabcXabcX"
^^^^^^^^^^^^ ^^^^^^^^^^^^
/.+?X/ ~ "abcXabcXabcX" /.+?/ ~ "abcXabcXabcX"
^^^^ ^
После этого мы имеем (?=
{contents}
)
, нулевую ширину
утверждение, взгляд вокруг. Эта сгруппированная конструкция соответствует
содержимое, но не считается совпадающим символом (нулевая ширина). Это
возвращается только в случае совпадения (утверждение).
Таким образом, другими словами, регулярное выражение /.+?(?=abc)/
означает:
Сопоставьте любые символы как можно меньше, пока не будет найдено "abc", без учета "abc".
Ответ 2
Если вы хотите захватить все до "abc":
/^(.*?)abc/
Пояснение:
( )
захватить выражение внутри круглых скобок для доступа с помощью $1
, $2
и т.д.
^
соответствует началу строки
.*
соответствовать чему-либо, ?
не жадному (соответствует минимальному количеству символов) - [1]
[1] Причина, по которой это необходимо, заключается в том, что в противном случае в следующей строке:
whatever whatever something abc something abc
по умолчанию, регулярные выражения являются жадными, то есть они будут соответствовать как можно больше. Поэтому /^.*abc/
будет соответствовать "независимо от чего-то что-то". Добавление не-жадного квантификатора ?
делает регулярное выражение только "независимо от чего-то".
Ответ 3
Как отметили @Jared Ng и @Issun, ключ для решения такого рода регулярных выражений, как "сопоставление всего до определенного слова или подстроки" или "сопоставление всего после определенного слова или подстроки", называется "косвенным" утверждением нулевой длины, Подробнее о них читайте здесь.
В вашем конкретном случае это можно решить путем позитивного взгляда в будущее. Одна картинка стоит тысячи слов. Смотрите подробное объяснение на скриншоте.
![Regex101 Screenshot]()
Ответ 4
Что вам нужно, посмотрите вокруг утверждения вроде .+? (?=abc)
.
Смотрите: Утверждения с нулевой длиной Lookahead и Lookbehind
Помните, что [abc]
не совпадает с abc
. Внутри скобок это не строка - каждый символ является лишь одной из возможностей. За пределами скобок она становится строкой.
Ответ 5
Для regex в Java, и я верю также в большинство движков регулярных выражений, если вы хотите включить последнюю часть, это будет работать:
.+?(abc)
Например, в этой строке:
I have this very nice senabctence
выберите все символы до "abc", а также включите abc
используя наше регулярное выражение, результат будет: I have this very nice senabc
Проверьте это: https://regex101.com/r/mX51ru/1
Ответ 6
Это будет иметь смысл в отношении регулярного выражения.
- Точное слово можно получить из следующей команды regex:
( "(. *?)" )/Г
Здесь мы можем получить точное слово глобально, которое входит в двойные кавычки.
Например,
Если наш текст поиска,
Это пример слов с двойными кавычками
то мы получим "двойное кавычку" из этого предложения.
Ответ 7
Я остановился на этом вопросе stackoverflow после поиска помощи для решения моей проблемы, но не нашел ее решения :(
Поэтому мне пришлось импровизировать... через некоторое время мне удалось найти необходимое мне регулярное выражение:
![enter image description here]()
Как видите, мне нужно было до одной папки впереди папки "grp-bps", без учета последней черты. И нужно было иметь хотя бы одну папку после папки "grp-bps".
Изменить
Текстовая версия для копирования-вставки (измените "grp-bps" для своего текста):
. */GRP-бит/[^/] +
Ответ 8
Я считаю, что вам нужны подвыражения. Если я правильно помню, вы можете использовать обычные скобки ()
для подвыражений.
Эта часть из руководства grep:
Back References and Subexpressions
The back-reference \n, where n is a single digit, matches the substring
previously matched by the nth parenthesized subexpression of the
regular expression.
Сделайте что-то вроде ^[^(abc)]
, чтобы сделать трюк.
Ответ 9
$
обозначает конец строки, поэтому что-то вроде этого должно работать: [[^abc]*]$
, где вы ищете что-то НЕ ЗАВЕРШЕНО в любой итерации abc
, но это должно быть в конце
Также, если вы используете язык сценариев с регулярным выражением (например, php или js), у них есть функция поиска, которая останавливается, когда она впервые встречает шаблон (и вы можете указать начало слева или начинать с правой стороны, или с php, вы можете сделать imode для зеркалирования строки).
Ответ 10
попробуйте это
.+?efg
Запрос:
select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual;
вывод:
hijklmn