繁体   English   中英

否定的超前匹配字符串,除非它以特定的单词出现。

[英]Negative Lookahead to match a string unless it appears in specific words.

我试图找到一种方法来确定某行是否包含特定的字符串,但同时如果出现在某些单词中则不匹配。 我有部分工作,但是如果其中一个排除词以关键字开头,它将失败。

因此,例如,此正则表达式: ^((?!custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic).)*(tom)

将成功排除列出的所有单词,但tomcat和明日除外。 我假设这是因为我正在匹配关键字,所以前瞻失败了,但是我不确定如何解决它。

更新:可悲的是,除非您在的两边都放否定的前瞻性,否则我无法弄清楚这一点. 在非捕获组中:

^(?:(?!custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic).(?!custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic))*?(tom).*

演示版


如果您移动,它会起作用. 在否定前瞻之前: .(?!...)

我也将* 重复设为lazy ,所以它不需要回溯太多(并非总是如此,但在此示例中如此)。 另外,如果要匹配整行并仅捕获tom的实例,请使包含.(?!...) 不捕获,并用贪婪的.*结束表达式:

^(?:.(?!custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic))*?(tom).*

演示版

除了在情况s1,s2,s3等情况下,这种情况听起来完全不匹配(或替换)模式

与其他潜在解决方案相比,正则表达式再简单不过了:

custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic|(tom)

如果您不仅要显示“ tom还想显示其中的整个单词,例如“ tomahawk ,请将其更改为:

custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic|(\w*tom\w*)

交替的左侧与您不需要的单词匹配。 我们将忽略这些匹配。 右侧将tom匹配并捕获到组1,我们知道它们是右侧的tom因为它们与左侧的表达式不匹配。

该程序显示了如何使用正则表达式(请参见在线演示底部的结果)。 它找到了tomtomahawk

import java.util.*;
import java.io.*;
import java.util.regex.*;
import java.util.List;

class Program {
public static void main (String[] args) throws java.lang.Exception  {

String subject = "custom onetomany manytomany atom tomcat tomorrow automatic tom tomahawk";
Pattern regex = Pattern.compile("custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic|(\\w*tom\\w*)");
Matcher regexMatcher = regex.matcher(subject);
List<String> group1Caps = new ArrayList<String>();

// put Group 1 captures in a list
while (regexMatcher.find()) {
if(regexMatcher.group(1) != null) {
group1Caps.add(regexMatcher.group(1));
}
} // end of building the list

System.out.println("\n" + "*** Matches ***");
if(group1Caps.size()>0) {
for (String match : group1Caps) System.out.println(match);
}

} // end main
} // end Program

参考

除了情况s1,s2,s3以外,如何匹配(或替换)模式...

我认为这是您追求的目标:

\b(?!(?:custom|onetomany|manytomany|atom|tomcat|tomorrow|automatic)\b)[a-z]*tom[a-z]*\b

我使用了单词边界( \\b )而不是锚( ^ ),因此它可以在任何地方找到该单词,而不仅仅是在开头。 最后添加另一个\\b可以确保它只匹配完整的单词。

超前子表达式末尾的\\b对过滤后的单词执行相同的操作。 例如,它不会automatic匹配,但 automatically匹配。

一旦超前通过, [az]*tom[az]*\\b与包含tom的单词(或更准确地说,是连续的字母序列)匹配。 我做了很多简化的假设,所以我可以专注于这项技术。 最重要的是,如果您的“单词”可以包含连字符( - )或撇号( ' )等非单词字符,则[az]*\\b可能不够好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM