正则表达式在Javascript中获取两个字符串之间的字符串

时间:2011-04-12 22:20:51

标签: javascript regex string

我发现了非常相似的帖子,但我不能在这里得到正则表达式。

我正在尝试编写一个正则表达式,它返回一个介于两个其他字符串之间的字符串。例如:我想获得字符串“cow”和“milk”之间的字符串

  

我的奶牛总是给牛奶

将返回

  

“总是给出”

这是我到目前为止拼凑的表达式:

(?=cow).*(?=milk)

然而,这会返回字符串“cow always give”

13 个答案:

答案 0 :(得分:148)

前瞻((?=部分)不消耗任何输入。这是一个零宽度断言(边界检查和外观检查)。

您希望在此处进行常规匹配,以消耗cow部分。要捕获其间的部分,可以使用捕获组(只需将要捕获的模式部分放在括号内):

cow(.*)milk

根本不需要前瞻。

答案 1 :(得分:50)

  

正则表达式在Javascript中获取两个字符串之间的字符串

在绝大多数情况下最完整的解决方案是使用捕获组并使用延迟点匹配模式。但是,JS正则表达式中的点.与换行符不匹配,因此,在100%的情况下,[^][\s\S] / [\d\D] / {{ 1}}构造。

ECMAScript 2018和更新的兼容解决方案

在支持 ECMAScript 2018 的JS环境中,[\w\W]修饰符允许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或更多的空格,然后匹配并消耗任何尽可能少的0+字符(=添加到匹配值),然后检查cow(在此子字符串之前有任何1/0或更多的空格)。

场景1:单行输入

所有JS环境都支持以下所有其他方案。请参阅答案底部的使用示例。

milk
首先找到

cow (.*?) milk ,然后找到一个空格,然后除了换行符之外的任何0 +字符,尽可能少的cow是一个惰性量词,被捕获到第1组然后a必须遵循*?的空格(并且匹配且消费)。

场景2:多行输入

milk

此处首先匹配cow ([\s\S]*?) milk 和空格,然后将尽可能少的0个字符匹配并捕获到组1中,然后匹配cow的空格。

场景3:重叠匹配

如果你有一个像milk这样的字符串,你需要在>>>15 text>>>67 text2>>> + >>> + numberwhitespace之间获得2个匹配,你可以& #39; t使用/>>>\d+\s(.*?)>>>/g,因为在找到第一个匹配项时>>> >>>已经消费之前,因此只能找到1个匹配项。您可以使用positive lookahead来检查文本的存在,而不会实际上&#34; gobbling&#34;它(即附加到比赛中):

67

查看online regex demo屈服/>>>\d+\s(.*?)(?=>>>)/g text1作为找到的第1组内容。

另见How to get all possible overlapping matches for a string

性能考虑因素

正则表达式模式中的惰性点匹配模式(text2)可能会在给定非常长的输入时减慢脚本执行速度。在许多情况下,unroll-the-loop technique在更大程度上有所帮助。我们试图从.*?中抓取cowmilk之间的所有内容,我们只需要匹配所有不以"Their\ncow\ngives\nmore\nmilk"开头的行,而不是{{} { 3}}我们可以使用:

milk

请参阅cow\n([\s\S]*?)\nmilk(如果可以/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm ,请使用\r\n)。使用这个小的测试字符串,性能增益可以忽略不计,但是对于非常大的文本,您会感觉到差异(特别是如果行很长并且换行不是很多)。

  

JavaScript中的示例正则表达式用法:

     

&#13;
&#13;
/cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
&#13;
&#13;
&#13;

答案 2 :(得分:48)

这是一个正则表达式,它将抓住牛与牛之间的东西(没有前导/尾随空间):

srctext = "My cow always gives milk.";
var re = /(.*cow\s+)(.*)(\s+milk.*)/;
var newtext = srctext.replace(re, "$2");

示例:http://jsfiddle.net/entropo/tkP74/

答案 3 :(得分:14)

  • 您需要捕获.*
  • 您可以(但不必)制作.* nongreedy
  • 真的没有必要进行前瞻。

    > /cow(.*?)milk/i.exec('My cow always gives milk');
    ["cow always gives milk", " always gives "]
    

答案 4 :(得分:6)

我能够在下面使用Martinho Fernandes的解决方案得到我需要的东西。代码是:

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

答案 5 :(得分:4)

选择的答案对我不起作用......嗯......

只需在奶牛之后和/或牛奶之前添加空间以修剪'#34;总是给#34;

/(?<=cow ).*(?= milk)/

enter image description here

答案 6 :(得分:2)

如何使用以下正则表达式:

(?<=My cow\s).*?(?=\smilk)

答案 7 :(得分:2)

如果数据位于多行中,则可能必须使用以下内容,

/My cow ([\s\S]*)milk/gm

My cow always gives 
milk

Regex 101 example

答案 8 :(得分:2)

您可以使用方法 match() 提取两个字符串之间的子字符串。试试下面的代码:

var str = "My cow always gives milk";
var subStr = str.match("cow(.*)milk");
console.log(subStr[1]);

输出:

<块引用>

总是给予

在此处查看完整示例:How to find sub-string between two strings

答案 9 :(得分:0)

给定语法,我发现正则表达式既繁琐又耗时。由于您已经在使用javascript,因此无需使用正则表达式即可更轻松地执行以下操作:

const text = 'My cow always gives milk'
const start = `cow`;
const end = `milk`;
const middleText = text.split(start)[1].split(end)[0]
console.log(middleText) // prints "always gives"

答案 10 :(得分:0)

任务

提取两个字符串之间的子字符串(不包括这两个字符串)

解决方案

let allText = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum";
let textBefore = "five centuries,";
let textAfter = "electronic typesetting";
var regExp = new RegExp(`(?<=${textBefore}\\s)(.+?)(?=\\s+${textAfter})`, "g");
var results = regExp.exec(allText);
if (results && results.length > 1) {
    console.log(results[0]);
}

答案 11 :(得分:0)

您可以使用结构调整来仅关注您感兴趣的部分。

因此您可以这样做:

let str = "My cow always gives milk";

let [, result] = str.match(/\bcow\s+(.*?)\s+milk\b/) || [];

console.log(result);

通过这种方式,您将忽略第一部分(完全匹配),而仅获得捕获组的匹配。如果您不确定完全没有匹配项,那么添加|| []可能会很有趣。在那种情况下,match将返回无法解构的null,因此在这种情况下,我们将返回[],然后result将是null。 / p>

附加的\b确保周围的单词“ cow”和“ milk”实际上是分开的单词(例如,不是“ milky”)。另外,还需要\s+来避免匹配中包含一些外部间距。

答案 12 :(得分:-1)

方法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]