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

2020/10/24 08:21 · javascript ·  · 0评论

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

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

我的牛总是喂牛奶

会回来

“总是给”

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

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

但是,这将返回字符串“牛总是给”。

前瞻(该(?=部分)不消耗任何输入。这是一个零宽度的断言(边界检查和后向检查也是如此)。

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

cow(.*)milk

完全不需要前瞻。

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

在绝大多数情况下,最完整的解决方案是使用具有惰性点匹配模式捕获组然而,一个点在JavaScript中的正则表达式不匹配换行符,所以,你会在100%的情况下工作是一种/ /构造。.[^][\s\S][\d\D][\w\W]

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

在支持ECMAScript 2018的JavaScript环境中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>>>并且您需要在>>>+ number+whitespace之间获得2个匹配项>>>,则您将无法使用/>>>\d+\s(.*?)>>>/g字符串因为在找到第一个匹配项>>>之前,before67已经被消耗掉,因此只能找到1个匹配项。您可以使用正向前瞻来检查文本是否存在,而无需实际“吞噬”文本(即追加到匹配项中):

/>>>\d+\s(.*?)(?=>>>)/g

请参见在线正则表达式演示产量text1text2第1组内容。

另请参见如何获取字符串的所有可能重叠匹配

性能考量

.*?如果输入的时间很长,则正则表达式模式中的惰性点匹配模式()可能会降低脚本的执行速度。在许多情况下,展开循环技术在更大程度上有所帮助。试图抓住之间的所有cowmilk来自"Their\ncow\ngives\nmore\nmilk"中,我们看到,我们只需要匹配不启动的所有行milk,因此,不是cow\n([\s\S]*?)\nmilk我们可以使用:

/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm

请参阅regex演示(如果可以\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");

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

  • 您需要捕获 .*
  • 您可以(但不必)使自己变得不.*贪心
  • 确实不需要前瞻。

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

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

只需在牛后和/或牛奶前添加空间以修剪“始终给”的空间

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

在此处输入图片说明

使用下面的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

考虑到语法,我发现正则表达式既繁琐又费时。由于您已经在使用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"

只需使用以下正则表达式:

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

如果数据在多行中,那么您可能必须使用以下内容,

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

My cow always gives 
milk

正则表达式101示例

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]

任务

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

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]);
}
本文地址:http://javascript.askforanswer.com/zhengzebiaodashiyihuoqujavascriptzhonglianggezifuchuanzhijiandezifuchuan.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!