[英]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
因为它们与左侧的表达式不匹配。
该程序显示了如何使用正则表达式(请参见在线演示底部的结果)。 它找到了tom
和tomahawk
。
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
参考
我认为这是您追求的目标:
\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.