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

246

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

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

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

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

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

  • 0
    Что вы подразумеваете под match but not including ?
  • 4
    Я имею в виду, что я хочу соответствовать "qwerty qwerty whatever " - не включая "abc". Другими словами, я не хочу, чтобы полученное совпадение было "qwerty qwerty whatever abc" .
Показать ещё 2 комментария
Теги:

9 ответов

510
Лучший ответ

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

/.+?(?=abc)/

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

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

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

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

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

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

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

Сопоставьте любые символы как можно меньше, пока не будет найдено "abc", без учета "abc".

  • 8
    Это, вероятно, не будет работать с переносами строк, если они должны быть захвачены.
  • 23
    Отличное описание функциональности кода.
Показать ещё 11 комментариев
68

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

/^(.*?)abc/

Пояснение:

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

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

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

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

whatever whatever something abc something abc

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

  • 2
    Спасибо, но ваш один действительно включает Азбуки в матче. Другими словами, полученное совпадение - «что угодно, что-то, abc».
  • 1
    Не могли бы вы объяснить, что вы в конечном итоге пытаетесь сделать? Если ваш сценарий: (A) Вы хотите получить все, что приводит к «abc» - просто используйте скобки вокруг того, что вы хотите захватить. (B) Вы хотите сопоставить строку с «abc» - вы все равно должны проверить abc, поэтому она должна быть частью регулярного выражения независимо от этого. Как еще можно проверить, что это там?
Показать ещё 8 комментариев
15

Как отмечали @Jared Ng и @Issun, ключ для решения такого типа RegEx, как "сопоставление всего до определенного слова или подстроки" или "сопоставление всего после определенного слова или подстроки" называется "lookaround" zero -length. Подробнее о них здесь.

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

Изображение 4750

8

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

Смотрите: Утверждения с нулевой длиной Lookahead и Lookbehind

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

1

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

.+?(abc)

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

I have this very nice senabctence

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

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

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

0

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

  • Точное слово можно получить из следующей команды regex:

( "(. *?)" )/Г

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

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

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

  • 0
    Добро пожаловать в StackOverflow и спасибо за вашу попытку помочь. Однако мне трудно понять, как это помогает цели, изложенной в вопросе. Можете ли вы уточнить? Можете ли вы применить его к приведенным примерам? Вы, кажется, сосредоточены на обработке " , что мне кажется несущественным для вопроса.
  • 0
    Привет, я объяснил, как получить слово или предложения между специальными символами. Здесь наш вопрос также «что-нибудь, пока последовательность специальных символов». поэтому я попытался с двойными кавычками и объяснил это здесь. Благодарю.
0

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

Эта часть из руководства 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
    Извините, это не работает. Ввод букв в скобках, похоже, не имеет никакого значения. Они по-прежнему рассматриваются как «ИЛИ b ИЛИ c».
-2

попробуйте это

.+?efg

Запрос:

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

вывод:

hijklmn
-2

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню