Java正则表达式需求:提取单引号外的所有字符串
解决Java正则提取单引号外字符串的问题
问题分析
你当前的正则无法区分单引号内/外的单词,因为单引号和内部单词之间有空格,导致(?!')这类断言无法生效——单引号内的单词前后是空格而非单引号,会被误匹配。另外还要注意字符串里的Mother''s是转义单引号(代表Mother's),处理时需要兼容这种情况。
可行方案:先清理单引号内容,再提取目标单词
最稳妥的方式是先移除所有单引号包裹的内容(包括含转义单引号的块),再从剩余文本中提取符合规则的单词:
步骤1:移除单引号内的内容
使用正则'([^']|'')*'匹配所有单引号块:
':匹配起始单引号([^']|'')*:匹配任意数量的「非单引号字符」或「转义单引号(两个连续单引号)」':匹配结束单引号
步骤2:提取目标单词
用你原来定义的正则(或简化版)提取剩余文本中的单词即可。
Java代码示例
import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StringExtractor { public static void main(String[] args) { String myString = "IF What young > old, 'Price 1', 'Prediction One', 'Mother''s Day', good"; // 移除所有单引号内的内容 String cleanedText = myString.replaceAll("'([^']|'')*'", ""); // 用你定义的正则提取目标单词 String myRegex = "\\b[a-zA-Z_]+\\d*[.]?[a-zA-Z_]*\\d*\\b"; Pattern pattern = Pattern.compile(myRegex); Matcher matcher = pattern.matcher(cleanedText); List<String> result = new ArrayList<>(); while (matcher.find()) { result.add(matcher.group()); } System.out.println(result); // 输出:[IF, What, young, old, good] } }
直接匹配的备选方案(进阶)
如果不想先清理文本,也可以用零宽断言直接匹配不在单引号内的单词,但逻辑更复杂:
String myRegex = "(?<!'(?:[^']|'')*)\\b[a-zA-Z_]+\\d*[.]?[a-zA-Z_]*\\d*\\b(?!(?:[^']|'')*')"; Pattern pattern = Pattern.compile(myRegex); Matcher matcher = pattern.matcher(myString); List<String> result = new ArrayList<>(); while (matcher.find()) { result.add(matcher.group()); }
这个正则通过(?<!'(?:[^']|'')*)确保单词前面没有未闭合的单引号块,(?!(?:[^']|'')*')确保单词后面没有未闭合的单引号块,从而只匹配单引号外的单词。不过实际场景中优先推荐第一种清理后提取的方式,更易维护。
内容的提问来源于stack exchange,提问作者5122014009
相关产品推荐
相关产品推荐

