Регулярное выражение для получения строки между двумя строками в Javascript
Я нашел очень похожие посты, но я не могу получить мое регулярное выражение прямо здесь.
Я пытаюсь написать регулярное выражение, которое возвращает строку, которая находится между двумя другими строками. Например: я хочу получить строку, которая находится между строками "корова" и "молоко".
Моя корова всегда дает молоко
вернется
"всегда дает"
Вот выражение, которое я сложил до сих пор:
(?=cow).*(?=milk)
Тем не менее, это возвращает строку "корова всегда дает".
Ответы
Ответ 1
Взгляд (часть (?=
) не потребляет никакого ввода. Это утверждение с нулевой шириной (как и граничные проверки и lookbehinds).
Вы хотите регулярное совпадение здесь, чтобы потреблять часть cow
. Чтобы захватить часть между ними, вы используете группу захвата (просто поместите часть паттерна, которую вы хотите захватить в скобках):
cow(.*)milk
Никакие образы не нужны вообще.
Ответ 2
Регулярное выражение для получения строки между двумя строками в JavaScript
Наиболее полное решение, которое будет работать в подавляющем большинстве случаев, - это использование группы захвата с ленивым шаблоном сопоставления точек. Тем не менее, точка .
в JavaScript регулярное выражение не совпадает с символами разрыва строки, поэтому в 100% случаев будут работать конструкции [^]
или [\s\S]
/[\d\D]
/[\w\W]
.
ECMAScript 2018 и более новые совместимые решения
В средах JavaScript, поддерживающих ECMAScript 2018, модификатор s
позволяет .
для сопоставления с любым символом, включая символы разрыва строки, и механизм регулярных выражений поддерживает вид сзади переменной длины. Таким образом, вы можете использовать регулярные выражения, такие как
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
В обоих случаях текущая позиция проверяется для cow
с любыми 1/0 или более пробелами после cow
, затем сопоставляются и потребляются любые как можно меньше символов 0+ (= добавляется к значению соответствия), а затем проверяется milk
для (с любыми 1/0 или более пробелами перед этой подстрокой).
Сценарий 1: однострочный ввод
Этот и все другие сценарии ниже поддерживаются всеми средами JavaScript. Смотрите примеры использования внизу ответа.
cow (.*?) milk
Сначала обнаруживается cow
, затем пробел, затем любые символы 0+, кроме символов разрыва строки, как можно меньше *?
является ленивым квантификатором, включается в группу 1, а затем должно следовать пространство с milk
(и те, которые сопоставляются и потребляются тоже).
Сценарий 2: многострочный ввод
cow ([\s\S]*?) milk
Здесь сначала сравнивают cow
и пространство, затем сопоставляют любые символы 0+, как можно меньше, и объединяют в группу 1, а затем сопоставляют пространство с milk
.
Сценарий 3: перекрывающиеся совпадения
Если у вас есть строка типа >>>15 text>>>67 text2>>>
и вам нужно получить 2 совпадения между >>>
+ number
+ whitespace
и >>>
, вы не можете использовать />>>\d+\s(.*?)>>>/g
поскольку при этом будет найдено только 1 совпадение, поскольку >>>
до 67
уже используется при поиске первого совпадения. Вы можете использовать позитивный взгляд, чтобы проверить наличие текста, фактически не "поглотив" его (т.е. добавив к совпадению):
/>>>\d+\s(.*?)(?=>>>)/g
Посмотрите онлайн-демонстрацию регулярных выражений, в которой text1
и text2
найдены в группе 1.
Также смотрите Как получить все возможные совпадения для строки.
Вопросы производительности
Шаблон сопоставления с отложенными точками (.*?
) Внутри шаблонов регулярных выражений может замедлить выполнение сценария, если задан очень длинный ввод. Во многих случаях техника "развернуть петлю" помогает в большей степени. Пытаясь перехватить все между cow
и milk
из "Their\ncow\ngives\nmore\nmilk"
, мы видим, что нам просто нужно сопоставить все строки, которые не начинаются с milk
, таким образом, вместо cow\n([\s\S]*?)\nmilk
мы можем использовать:
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
Посмотрите демонстрационный пример регулярных выражений (если есть возможность \r\n
, используйте /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
) С этой небольшой тестовой строкой прирост производительности незначителен, но при очень большом тексте вы почувствуете разницу (особенно если строки длинные, а разрывы строк не очень многочисленны).
Пример использования регулярных выражений в JavaScript:
//Single/First match expected: use no global modifier and access match[1]
console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]);
// Multiple matches: get multiple matches with a global modifier and
// trim the results if length of leading/trailing delimiters is known
var s = "My cow always gives milk, thier cow also gives milk";
console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);}));
//or use RegExp#exec inside a loop to collect all the Group 1 contents
var result = [], m, rx = /cow (.*?) milk/g;
while ((m=rx.exec(s)) !== null) {
result.push(m[1]);
}
console.log(result);
Ответ 3
Здесь регулярное выражение, которое будет захватывать то, что между коровой и молоком (без начального/конечного пространства):
srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");
Пример: http://jsfiddle.net/entropo/tkP74/
Ответ 4
- Вам нужно захватить
.*
- Вы можете (но не обязательно) сделать
.*
nongreedy
-
На самом деле нет необходимости в поиске.
> /cow(.*?)milk/i.exec('My cow always gives milk');
["cow always gives milk", " always gives "]
Ответ 5
Я смог получить то, что мне было нужно, используя решение Мартино Фернандеса, приведенное ниже. Код является:
var test = "My cow always gives milk";
var testRE = test.match("cow(.*)milk");
alert(testRE[1]);
Вы заметите, что я оповещаю переменную testRE как массив. Это потому, что testRE по какой-то причине возвращается как массив. Выход из:
My cow always gives milk
Изменения в:
always gives
Ответ 6
Выбранный ответ не работает для меня... хм...
Просто добавьте пробел после коровы и/или перед молоком, чтобы урезать пробелы из "всегда дает"
/(?<=cow ).*(?= milk)/
![enter image description here]()
Ответ 7
Просто используйте следующее регулярное выражение:
(?<=My cow\s).*?(?=\smilk)
Ответ 8
Метод match() ищет в строке совпадение и возвращает объект Array.
// Original string
var str = "My cow always gives milk";
// Using index [0] would return<br/>
// "**cow always gives milk**"
str.match(/cow(.*)milk/)**[0]**
// Using index **[1]** would return
// "**always gives**"
str.match(/cow(.*)milk/)[1]