Как сопоставить «что-нибудь до этой последовательности символов» в регулярном выражении? - PullRequest
416 голосов
/ 19 августа 2011

Возьмите это регулярное выражение: /^[^abc]/.Это будет соответствовать любому отдельному символу в начале строки, кроме a, b или c.

Если вы добавите * после него - /^[^abc]*/ - регулярное выражение будет продолжать добавлять каждый последующийсимвол результата, пока не встретится a, или b, или c.

Например, с исходной строкой "qwerty qwerty whatever abc hello", выражение будет соответствовать до "qwerty qwerty wh".

Но что, если бы я хотел, чтобы совпадающая строка была "qwerty qwerty whatever "

... Другими словами, как я могу сопоставить все до (но не включая) точной последовательности "abc"?

Ответы [ 10 ]

826 голосов
/ 19 августа 2011

Вы не указали, какой тип регулярного выражения вы используете, но это работать в любом из самых популярных, которые можно считать «завершенными».

/.+?(?=abc)/

Как это работает

Часть .+? является не жадной версией .+ (одна или несколько что-нибудь). Когда мы используем .+, двигатель будет в основном соответствовать всем. Затем, если в регулярном выражении есть что-то еще, оно будет возвращаться пошагово пытаясь сопоставить следующую часть. Это жадное поведение, значение максимально удовлетворить .

При использовании .+? вместо сопоставления всех сразу и возврата к другие условия (если есть), двигатель будет соответствовать следующим символам шаг до следующей части регулярного выражения (снова, если таковые имеются). Это не жадный , что означает соответствие наименьшему возможному удовлетворяют .

/.+X/  ~ "abcXabcXabcX"        /.+/  ~ "abcXabcXabcX"
          ^^^^^^^^^^^^                  ^^^^^^^^^^^^

/.+?X/ ~ "abcXabcXabcX"        /.+?/ ~ "abcXabcXabcX"
          ^^^^                          ^

После этого имеем (?={contents}), нулевой ширины утверждение , оглядывается . Эта сгруппированная конструкция соответствует содержимое, но не считается совпадением символов ( нулевая ширина ). Это возвращается только в случае совпадения или нет ( утверждение ).

Таким образом, другими словами, регулярное выражение /.+?(?=abc)/ означает:

Подбирайте как можно меньше символов, пока не найдете "abc", не считая "abc".

98 голосов
/ 19 августа 2011

Если вы хотите захватить все до «abc»:

/^(.*?)abc/

Пояснение:

( ) захватить выражение в скобках для доступа, используя $1, $2 и т. Д.

^ соответствует началу строки

.* соответствует любому, ? не жадно (соответствует минимальному количеству символов) - [1]

[1] Причина, по которой это необходимо, заключается в том, что в противном случае в следующей строке:

whatever whatever something abc something abc

по умолчанию, регулярные выражения жадные , что означает, что оно будет максимально соответствовать. Следовательно, /^.*abc/ будет соответствовать «что угодно, что угодно, что угодно». Добавление не жадного квантификатора ? позволяет регулярному выражению совпадать только «что угодно, что угодно».

36 голосов
/ 21 сентября 2015

Как отметили @Jared Ng и @Issun, ключ для решения такого рода RegEx, как «сопоставление всего до определенного слова или подстроки» или «сопоставление всего после определенного слова или подстроки», называется «нулевым поиском» нуляутверждения. Подробнее о них можно прочитать здесь.

В вашем конкретном случае это можно решить, если заглянуть в будущее.Одна картинка стоит тысячи слов.Смотрите подробное объяснение на скриншоте.

Regex101 Screenshot

8 голосов
/ 19 августа 2011

Что вам нужно, так это осмотреть утверждение вроде .+? (?=abc).

См .: Утверждения нулевой длины с заглядыванием вперед и назад

Имейте в виду, что [abc] isn 'т так же, как abc.Внутри скобок это не строка - каждый символ - только одна из возможностей.За скобками он становится строкой.

3 голосов
/ 30 ноября 2016

Для регулярных выражений в Java, и я полагаю, также в большинстве движков регулярных выражений, если вы хотите включить последнюю часть, это будет работать:

.+?(abc)

Например, в этой строке:

I have this very nice senabctence

выберите все символы до "abc" и также включите abc

, используя наше регулярное выражение, результат будет: I have this very nice senabc

Проверьте это: https://regex101.com/r/mX51ru/1

2 голосов
/ 25 мая 2017

Это будет иметь смысл для регулярного выражения.

  1. Точное слово можно получить из следующей команды регулярного выражения:

("(. *?)") / g

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

Это пример для слов "двойные кавычки"

, тогда мы получим "двойные кавычки" из этого предложения.

0 голосов
/ 20 ноября 2018

Я закончил с этим вопросом о стековом потоке после поиска помощи в решении моей проблемы, но не нашел ее решения: (

Так что мне пришлось импровизировать ... через некоторое время мне удалось найти необходимое мне регулярное выражение:

enter image description here

Как видите, мне нужно было до одной папки перед папкой "grp-bps", без последней черты. И это былонеобходимо иметь хотя бы одну папку после папки "grp-bps".

0 голосов
/ 28 октября 2016

попробуйте

.+?efg

Запрос:

select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual;

вывод:

hijklmn
0 голосов
/ 19 августа 2011

Полагаю, вам нужны подвыражения. Если я правильно помню, вы можете использовать обычные () скобки для подвыражений.

Эта часть из руководства 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)], добейтесь цели.

0 голосов
/ 19 августа 2011

$ отмечает конец строки, поэтому должно работать что-то вроде этого: [[^abc]*]$, где вы ищете что-либо, НЕ ЗАВЕРШАЮЩЕЕ в любой итерации abc, но это должно быть в конце

Кроме того, если вы используете язык сценариев с регулярным выражением (например, php или js), у них есть функция поиска, которая останавливается при первом обнаружении шаблона (и вы можете указать начало слева или начало справа, или с помощью php вы можете выполнить развертывание, чтобы отразить строку).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...