我发现了非常相似的帖子,但我不能在这里得到我的正则表达式。
我正在尝试编写一个正则表达式,它返回一个位于其他两个字符串之间的字符串。例如:我想获取位于字符串“cow”和“milk”之间的字符串。
我的牛总是产奶
会回来
“总是给予”
这是我到目前为止拼凑的表达方式:
(?=cow).*(?=milk)
但是,这会返回字符串“cow always Gives”。
我发现了非常相似的帖子,但我不能在这里得到我的正则表达式。
我正在尝试编写一个正则表达式,它返回一个位于其他两个字符串之间的字符串。例如:我想获取位于字符串“cow”和“milk”之间的字符串。
我的牛总是产奶
会回来
“总是给予”
这是我到目前为止拼凑的表达方式:
(?=cow).*(?=milk)
但是,这会返回字符串“cow always Gives”。
前瞻(那(?=
部分)不消耗任何输入。这是一个零宽度断言(边界检查和后视)。
您想要在这里进行常规匹配,以消耗该cow
部分。要捕获两者之间的部分,请使用捕获组(只需将要捕获的模式部分放在括号内):
cow(.*)milk
根本不需要前瞻。
JavaScript 中获取两个字符串之间的字符串的正则表达式
适用于绝大多数情况的最完整的解决方案是使用具有惰性点匹配模式的捕获组。然而,一个点在JavaScript中的正则表达式不匹配换行符,所以,你会在100%的情况下工作是一种或/ /构造。.
[^]
[\s\S]
[\d\D]
[\w\W]
在支持ECMAScript 2018 的JavaScript 环境中,s
修饰符允许.
匹配任何字符,包括换行符,并且正则表达式引擎支持可变长度的lookbehinds。所以,你可以使用像这样的正则表达式
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 或更多空格)。
所有 JavaScript 环境都支持此方案和以下所有其他方案。请参阅答案底部的使用示例。
cow (.*?) milk
cow
首先找到,然后是一个空格,然后是除换行符以外的任何 0+ 字符,尽可能少*?
的惰性量词,被捕获到组 1 中,然后是一个milk
必须跟随的空格(这些也被匹配和消耗) )。
cow ([\s\S]*?) milk
在这里,cow
首先匹配一个空格,然后匹配任何尽可能少的0+字符并捕获到组1中,然后milk
匹配一个空格。
如果您有一个像这样的字符串>>>15 text>>>67 text2>>>
并且您需要在>>>
+ number
+whitespace
和之间获得 2 个匹配项>>>
,则不能使用,/>>>\d+\s(.*?)>>>/g
因为这只会找到 1 个匹配项,因为在找到第一个匹配项时已经消耗了>>>
before 。您可以使用正向前瞻来检查文本是否存在,而无需实际“吞噬”它(即附加到匹配项):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);
使用现代
String#matchAll
方法const s = "My cow always gives milk, thier cow also gives milk"; const matches = s.matchAll(/cow (.*?) milk/g); console.log(Array.from(matches, x => x[1]));
这是一个正则表达式,它将获取牛和牛奶之间的内容(没有前导/尾随空间):
srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");
.*
.*
贪婪真的不需要前瞻。
> /cow(.*?)milk/i.exec('My cow always gives milk');
["cow always gives milk", " always gives "]