我发现了非常相似的帖子,但是我不能在这里正确获取正则表达式。
我正在尝试编写一个正则表达式,该返回一个介于其他两个字符串之间的字符串。例如:我想获取字符串“ 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
请参见在线正则表达式演示产量text1
和text2
第1组内容。
另请参见如何获取字符串的所有可能重叠匹配。
性能考量
.*?
如果输入的时间很长,则正则表达式模式中的惰性点匹配模式()可能会降低脚本的执行速度。在许多情况下,展开循环技术在更大程度上有所帮助。试图抓住之间的所有cow
和milk
来自"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
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]);
}
文章标签:javascript , regex , string
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!