English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Регулярное выражение нулевого шириной совпадения:
Нулевой шириной совпадение - это难点 регулярного выражения, поэтому в этой главе мы анализируем его с точки зрения принципа совпадения. У нулевого шириной совпадения есть и другие названия, такие как "вращение" или "предварительный поиск" и т.д., но это не является нашей основной темой.
1. Основные концепции:
Нулевой шириной совпадение, как его имя говорит, это совпадение нулевого размера, совпаденное содержимое не сохраняется в результате совпадения, в конечном итоге результат совпадения только позиция.
Его функция - добавить ограничивающие условия на указанное положение, чтобы определить, что символы до или после этой позиции должны соответствовать ограничивающим условиям, чтобы выражение в регулярном выражении могло успешно совпасть с выражением.
Примечание: Здесь所说的 подвыражение не только выражение, заключенное в круглые скобки, но и любая единица совпадения в регулярном выражении.
JavaScript поддерживает только нулевой шириной先行ное совпадение, а нулевой шириной先行ное совпадение можно разделить на направленный нулевой шириной先行ное совпадение и негативный нулевой шириной先行ное совпадение.
Пример кода:
Пример кода之一:
var str="abZW863"; var reg=/ab(?=[A-Z])/; console.log(str.match(reg));
В этом коде семантика регулярного выражения: совпадение строки, следующей за любой большой буквой, "ab". Результат совпадения "ab", так как нулевой шириной "(?=[A-Z])" не совпадает с любым символом, он используется только для того, чтобы определить, что позиция за текущей позицией должна быть большой буквой.
Пример кода之二:
var str="abZW863"; var reg=/ab(?![A-Z])/; console.log(str.match(reg));
В этом коде семантика регулярного выражения: совпадение строки, не следующей за любой большой буквой, "ab". Регулярное выражение не совпало с любым символом,因为在 строке, за "ab" следует большая буква.
2. Принцип совпадения:
Этот код просто介绍了, как нулевой шириной совпадает с помощью концепции.
Ниже мы кратко介绍一下, как направленный нулевой шириной и негативный нулевой шириной совпадают с помощью метода совпадения.
1. Направленный нулевой шириной
Пример кода:
var str="<div>antzone"; var reg=/^(?=<)<[^>]+>\w+/; console.log(str.match(reg));
Процесс соответствия следующим образом:
Сначала контроль переходит к "^", сначала начинается с позиции 0 для совпадения, он совпадает с началом позиции 0, совпадение успешное, затем контроль передается "(?=<)", , так как "^" является нулевым шириной, поэтому "(?=<)" также начинается с позиции 0 для совпадения, он требует, чтобы позиция справа была символом "<", позиция 0 справа正好 является символом "<", совпадение успешное, затем контроль передается "<", так как "(?=<)" также является нулевым шириной, поэтому он также начинается с позиции 0 для совпадения, и совпадение успешное, дальнейший процесс совпадения не рассматривается.
2. Негативная нулевая широта:
Пример кода:
var str="abZW863ab88"; var reg=/ab(?![A-Z])/g; console.log(str.match(reg));
Процесс соответствия следующим образом:
Сначала управление передается символу "a", начальная позиция 0, успешное соответствие символу "a", затем управление передается "b", начальная позиция 1, успешное соответствие символу "b", затем управление передается "(?![A-Z])", он начинает соответствие с позиции 2, он требует, чтобы справа от текущей позиции не было ни одной большой буквы, а справа от текущей позиции — большая буква "Z", соответствие не успешное, затем управление возвращается к символу "a", и又开始 попытка соответствия с позиции 1, не успешное соответствие, затем управление снова передается символу "a", и又开始 попытка соответствия с позиции 2, не успешное соответствие, и так далее, до попытки соответствия с позиции 7, которая успешна, затем управление передается "b", и又开始 попытка соответствия с позиции 8, успешное соответствие, затем управление передается "(?![A-Z])", он又开始 попытку соответствия с позиции 9, он требует, чтобы справа от текущей позиции не было большой буквы, успешное соответствие, но он не действительно соответствует символу, поэтому конечный результат соответствия — "ab".
Ниже приведены дополнения
Нулевая широта — это один из методов регулярных выражений, регулярное выражение в компьютерной науке — это единственная строка, которая используется для описания или соответствия набору строк, соответствующих определенным грамматическим правилам.
Определение и объяснение
Нулевая широта — это один из методов регулярных выражений
Регулярное выражение в компьютерной науке — это единственная строка, которая используется для описания или соответствия набору строк, соответствующих определенным грамматическим правилам. Во многих текстовых редакторах или других инструментах регулярные выражения обычно используются для поиска и/или замены текста, соответствующего определенному шаблону. Многие языки программирования поддерживают использование регулярных выражений для операций со строками. Например, в Perl встроен мощный движок регулярных выражений. Концепция регулярных выражений была впервые普及ized в утилитах Unix (например, sed и grep). Регулярные выражения обычно сокращаются до “regex”, единственное число — regexp, regex, множественное число — regexps, regexes, regexen.
Zero-width assertion
Used to find something before or after certain content (but not including these contents), that is, they are like \b, ^, $, used to specify a position that should meet certain conditions (i.e., assertions), so they are also called zero-width assertions. It is best to illustrate with examples: assertions are used to declare a fact that should be true. In regular expressions, matching will only continue when the assertion is true.
(?=exp) also known as zero-width positive lookahead assertion, asserts that the position after its occurrence can match the expression exp. For example, \b(?=re)\w+\b matches the part of the word starting with re (except for re itself), for example, when searching for reading a book., it matches ading.
var reg = new Regex(@"\w+(?=ing)"); var str = "muing"; Console.WriteLine(reg.Match(str).Value); // возвращается mu
(?<=exp) also known as zero-width positive lookbehind assertion, asserts that the position before its occurrence can match the expression exp. For example, \b\w+(?<=ing\b) matches the first part of the word ending with ing (except for ing itself), for example, when searching for I am reading., it matches read.
If you want to add a comma every three digits in a long number (of course, starting from the right), you can find the parts that need to be added in front and inside like this: ((?=\d)\d{3})+\b, when used to search for 1234567890, the result is 234567890.
В следующем примере используются оба этих предсказывающих先行ных: (?<=\s)\d+(?=\s) совпадает с числами, разделенными пробелами (еще раз подчеркиваю, не включая эти пробелы).
Negative zero-width assertion
We mentioned earlier how to find characters that are not a certain character or not in a certain character class (negative). But what if we just want to make sure that a certain character does not appear, but do not want to match it? For example, if we want to find such a word - it contains the letter q, but q is not followed by the letter u, we can try like this:
Мatching of words containing the letter q followed by a letter that is not u. But if you do more tests (or if you are sufficiently sharp-witted and notice it directly), you will find that if q appears at the end of a word, like Iraq, Benq, this expression will fail. This is because [^u] always matches a character, so if q is the last character of a word, the [^u] will match the word separator (which could be a space, or a period, or something else) after q, and the \w*\b will match the next word, so \b\w*q[^u]\w*\b will match the entire Iraq fighting. Negative zero-width assertions can solve this problem because they only match a position and do not consume any characters. Now, we can solve this problem like this: \b\w*q(?!u)\w*\b.
Нулевое шириной негативное прогностическое утверждение (?!exp), утверждает, что после этого положения не может соответствовать выражению exp. Например: \d{3}(?!\d) соответствует трем цифрам, и после этих трех цифр не может быть цифры; \b((?!abc)\w)+\b соответствует слову, не содержащему последовательности символов abc.
Аналогично, мы можем использовать (?<!exp), нулевое шириной негативное регрессивное утверждение, чтобы утверждать, что перед этим положением не может соответствовать выражению exp: (?<![a-z])\d{7} соответствует семизначным числам, которые не начинаются с малой буквы.
Более сложный пример: (?<=<(\w+)>).*(?=<\/\1>) соответствует содержимому простого HTML-тега без атрибутов. (<?=(\w+)>) определяет这样的 префикс: слово, заключенное в угловые скобки (например, может быть <b>), затем является *(любой строкой), в конце является суффикс (?=<\/\1>). Обратите внимание на суффикс \/, он использует前面提到的 экранирование символов; \1 - это обратная ссылка, которая ссылается на первое захваченное grupo, содержимое которого соответствует (\w+) соответствия, поэтому, если префикс на самом деле <b>, суффикс будет </b>. Вся выражение соответствует содержимому между <b> и </b> (еще раз напоминаем, что не включает префикс и суффикс самих себя).
Немного сложно понять上面的. Давайте добавим немного补充:
Утверждения используются для объявления факта, который должен быть истинным. В регулярных выражениях匹配 продолжается только при истинности утверждения.
Следующие четыре используются для поиска того, что находится перед или после определенного контента (но не включает этот контент), то есть они, как \b, ^, $, используются для указания места, которое должно соответствовать определенным условиям (т.е. утверждения), поэтому они также называются нулевыми утверждениями. Лучше всего объяснить с помощью примеров:
(?=exp) также называется нулевым шириной позитивным прогностическим утверждением, оно утверждает, что после его появления может соответствовать выражению exp. Например, \b\w+(?=ing\b) соответствует части слова, заканчивающегося на ing (кроме ing), например, при поиске I'm singing while you're dancing, оно соответствует sing и danc.
(?<=exp) также называется нулевым шириной позитивным регрессивным утверждением, оно утверждает, что перед его появлением может соответствовать выражению exp. Например, (?<=\bre)\w+\b соответствует части слова, начинающегося на re (кроме re), например, при поиске reading a book, оно соответствует ading.
Если вы хотите добавить запятую каждые три знака в очень длинном числе (естественно, начиная справа), вы можете так найти части, в которых нужно добавить и перед и внутри запятой: ((?<=\d)\d{3})*\b, его использование для поиска в 1234567890 приводит к результату 234567890。
В следующем примере используются оба этих предсказывающих先行ных: (?<=\s)\d+(?=\s) совпадает с числами, разделенными пробелами (еще раз подчеркиваю, не включая эти пробелы).
Дополнение два:
Недавно, чтобы обработать исходный код html файла, необходимо было выполнить поиск по регулярному выражению и заменить. При этом воспользовавшись этим шансом, я изучил регулярные выражения систематически, хотя и раньше использовал регулярные выражения, но каждый раз это было только временно изучено, чтобы успешно пройти. В процессе обучения я встретил немало проблем, особенно нулевая ширина предсказующий先行ный (здесь также хочу пожаловаться, что везде в Интернете到处 такие копирующие и вставляющие содержимое, при встрече проблемы искал много повторяющегося контента, пот), поэтому я записал здесь свое понимание, чтобы в будущем было удобно для поиска!
Что такое нулевая ширина прогнозирующий先行ный? Давайте посмотрим на официальное определение msdn
(?= Подexpressия)
(Прогнозирующий先行ный нулевая широта.) Совпадение продолжается только если подexpressия в этой позиции справа совпадает. Например, \w+(?=\d) совпадает с словами, следующими за числом, а не с самим числом.
Классический пример: получение содержимого перед ing, если слово заканчивается на ing
var reg = new Regex(@"\w+(?=ing)"); var str = "muing"; Console.WriteLine(reg.Match(str).Value); // возвращается mu
Это примеры, которые можно найти везде в Интернете, может быть, вы уже поняли, что это просто возвращается содержимое перед выражением exp.
Посмотрим на следующий код
var reg = new Regex(@"a(?=b)c"); var str = "abc"; Console.WriteLine(reg.IsMatch(str)); // возвращается false
Почему возвращается false?
Действительно, официальное определение msdn уже сказано, просто оно сказано слишкомofficialно. Здесь нам нужно обратить внимание на ключевой момент: это положение. Да, это положение, а не символ. Давайте рассмотрим второй пример, сочетая официальное определение и первый пример:
Потому что после a следует b, то в этот раз возвращается совпадение содержимого a (как известно из первого примера, возвращается только a, а не содержимое совпадения exp), поэтому часть a(?=b)c уже решена,接下来需要解决c совпадения проблемы, поэтому совпадение c должно начинаться с какой-то части строки abc, учитывая официальное определение, известно, что это начинается с позиции подexpressии в правую сторону, поэтому это начинается с позиции b, но b не совпадает с оставшейся частью c a(?=b)c, поэтому abc не совпадает с a(?=b)c.
Тогда как должны быть написаны регулярные выражения для вышеуказанного совпадения?
Ответ: a(?=b)bc
Конечно, кто-то скажет, что можно просто abc, чтобы совпало, зачем все это? Конечно, не нужно все это, просто чтобы объяснить, что такое нулевая широта положительная прогнозирующая привидение? Принцип других нулевых широтных привидений также один и тот же!
Дополнение три
(?=exp): нулевая широта положительная прогнозирующая привидение, которая утверждает, что положение自身 может совпадать с выражением exp.
#Совпадение после _path, результат product
'product_path'.scan /(product)(?=_path)/
(?<=exp): нулевая широта положительная обратная привидение, которая утверждает, что положение自身 может совпадать с выражением exp
#Совпадение перед name:, результат wangfei
'name:wangfei'.scan /(?<=name:)(wangfei)/ #wangfei
(?!exp): нулевая широта положительная обратная привидение, которая утверждает, что после этого положения не может совпадать выражение exp.
#Совпадение после _path
'product_path'.scan /(product)(?!_path)/ #nil
#Совпадение после _url
'product_path'.scan /(product)(?!_url)/ #product
(?!exp): нулевая широта отрицательная обратная привидение, которая утверждает, что перед этим положением не может совпадать выражение exp
#Совпадение перед name:
'name:angelica'.scan /(?<!name:)(angelica)/ #nil
#Совпадение перед nick_name:
'name:angelica'.scan /(?<!nick_name:)(angelica)/#angelica
Редактор также устал от этой вещи, ждите чего-то хорошего, сегодня умойтесь и лягте спать