正则表达式 匹配两个字符串之间的所有字符

696

例子: This is just\na simple sentence.

我想匹配在 This issentence 之间的每一个字符。忽略换行符。我无法找出正确的语法。

18个回答

1039
例如
(?<=This is)(.*)(?=sentence)

Regexr

我使用了lookbehind(?<=)和look ahead(?=),这样就不会在匹配时包括"This is" 和 "sentence",但这取决于您的用例,您也可以简单地编写This is(.*)sentence

这里重要的是您要激活正则表达式引擎中的“dotall”模式,以便.匹配换行符。但如何实现这一点取决于您的正则表达式引擎。

接下来需要考虑使用.*还是.*? 。第一个是贪婪模式,将匹配到字符串中最后一个"sentence",而第二个是非贪婪模式,将匹配到字符串中下一个"sentence"。

更新

Regexr

This is(?s)(.*)sentence

当 (?s) 开启 dotall 修饰符时,. 将匹配换行符。

更新2:

(?<=is \()(.*?)(?=\s*\))

是否与您的示例"This is (a simple) sentence"匹配。请查看Regexr


1
@tchrist,抱歉我不得不查一下。我的理解是 This is(?s)(.*)sentence 可以工作? - stema
1
这基本上解决了我的问题,但是如何在我的模式中包含一个空格字符呢? 我尝试了以下内容:"(.*?)())" 来匹配序列末尾的“ )”,但它没有起作用。 - 0xbadf00d
37
仅一提醒 - regexr 现在表示 JavaScript 不支持后顾断言。 - Kovo
@MohasinAli 这是一个命令开关。对于每种语言实现都不同。请查看您的语言注释以获取详细信息。 - Keng
5
有没有办法来处理文本块中这种重复出现的拆分?例如:“This is just\na simple sentence. Here is some additional stuff. This is just\na simple sentence. And here is some more stuff. This is just\na simple sentence. ”目前它匹配整个字符串,而不是每个实例。 - jzadra
显示剩余12条评论

283

需要懒惰量词

重新提出这个问题,因为接受答案中的正则表达式似乎对我来说不完全正确。为什么呢? 因为

(?<=This is)(.*)(?=sentence)

This is my first sentence. This is my second sentence. 中,my first sentence. This is my second 将匹配。

查看示例

你需要在两个lookaround之间加入一个lazy quantifier。在星号后面添加一个 ? 使它变为lazy。

这就是你想要的匹配结果:

(?<=This is).*?(?=sentence)

查看演示。我移除了不必要的捕获组。

使用DOTALL模式跨越换行匹配

请注意,在演示中设置了“点匹配所有字符模式”(即dot-all)(请参见如何在各种语言中打开DOTALL模式)。在许多正则表达式版本中,您可以使用在线修饰符(?s)来设置它,使表达式变为:

(?s)(?<=This is).*?(?=sentence)

参考资料


1
你关于捕获组的理解是正确的。我不知道为什么会这样做。但是.*.*?之间的区别也在我的答案中有所解释(“更新”前的段落)。因此,我认为我的答案是正确的。 - stema
3
@stema 抱歉挑刺,昨天在浏览你的一些答案时,那是唯一让我有点不爽的答案。 :) 我把第一行从“是错误的”改成了“在我看来似乎不完全正确”... 希望这不会让 不爽,可能只是关于应该使用什么正则表达式来处理这样一个高流量答案的感知差异。 - zx81
@zx81 (?<=排除这个).*?(?=和排除这个) 这是一个很棒的答案,谢谢。我以为我懂正则表达式,但这让我又重新阅读了一遍相关内容 :) 每天都有新的学习机会 :) - AD Progress

79

尝试使用 This is[\s\S]*?sentence,可以在JavaScript中工作。


如何以这种方式执行惰性查找? - AGamePlayer
5
@AwQiruiGuo 和上面一样。[\s\S]*?(也称为:非贪婪通配符) - phil294
也适用于Notepad++ - undefined

27

这个:

This is (.*?) sentence

在 JavaScript 中运作。


1
我喜欢简单明了,但对我来说不够用。我的意思是,"This is just\na simple sentence".match(/This is (.*?) sentence/) 返回了 null。而 "This is just\na simple sentence".match(/This is (.*?) sentence/s) 则返回了有用的结果。区别在于最后一个斜杠后面的 DOTALL s - Marcus

19
请使用以下正则表达式: (?<=beginningstringname)(.*\n?)(?=endstringname)

不知道为什么会有这么多赞,这允许0-1行断点,并且换行符必须紧接在 endstringname 之前。 - OGHaza
我发现删除日志行的开头(时间戳等)很有用。我使用换行符作为开始字符串,使用“at”作为结束字符串。 - Stan
为什么要使用捕获组而不仅仅是匹配 .*\n?(在环视之间),为什么不只是 .* - undefined

5
在 JavaScript 中,您可以使用[^]匹配包括换行符在内的任何字符
使用带有点号./s标志来匹配任何字符也可以起作用,但是应用于整个模式,JavaScript不支持内联修饰符来开启/关闭标志。
为了尽可能少地匹配字符,您可以通过添加问号使量词非贪婪,并使用捕获组提取中间部分。
This is([^]*?)sentence

查看regex101演示

顺便提一下,为了不匹配部分单词,您可以使用单词边界,例如\bThissentence\b

const s = "This is just\na simple sentence";
const regex = /This is([^]*?)sentence/;
const m = s.match(regex);

if (m) {
  console.log(m[1]);
}


JavaScript中的lookaround变体是(?<=This is)[^]*?(?=sentence),您可以查看JS正则表达式中的回顾以获取支持。
还请参阅关于回顾的重要说明

const s = "This is just\na simple sentence";
const regex = /(?<=This is)[^]*?(?=sentence)/;
const m = s.match(regex);

if (m) {
  console.log(m[0]);
}


5

这对我很有用(我正在使用VS Code):

对于: This is just\na simple sentence

使用: This .+ sentence


4
你可以简单地使用这个:\This is .*? \sentence

这是我在 vscode 中的最终正则表达式,它提取了 #<Inventory:0x000055c8a2966b60 id: nil, batch_code: "10324" 并只留下了 "10324"。 - buncis

3

使用Java方法进行正则表达式匹配两个字符串之间的所有内容。

List<String> results = new ArrayList<>(); //For storing results
String example = "Code will save the world";

让我们使用Pattern和Matcher对象来使用正则表达式(.?)*

Pattern p = Pattern.compile("Code "(.*?)" world");   //java.util.regex.Pattern;
Matcher m = p.matcher(example);                      //java.util.regex.Matcher;

由于Matcher可能包含多个匹配项,我们需要循环处理结果并将其存储。

while(m.find()){   //Loop through all matches
   results.add(m.group()); //Get value and store in collection.
}

这个例子只包含"will save the"这个词,但在更大的文本中可能会找到更多匹配项。


2
如果有人想在Jenkins环境中找到这一示例,它会解析build.log文件,如果找到匹配项就会导致构建失败。
import java.util.regex.Matcher;
import java.util.regex.Pattern;

node{    
    stage("parse"){
        def file = readFile 'build.log'

        def regex = ~"(?s)(firstStringToUse(.*)secondStringToUse)"
        Matcher match = regex.matcher(file)
        match.find() {
            capturedText = match.group(1)
            error(capturedText)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接