Java 模式匹配器错误匹配子字符串

Java Pattern Matcher Incorrectly matches sub string

我有一个位于特定文件路径的文件夹列表 当通过下面的代码搜索时,它会给出以下文件列表

File[] fileList = folderListLocation.listFiles(someFileFilter);
//it gives following list
fileList=[NUTS, BOLTS, CAR_COMPONENTS_ADT,CAR_COMPONENTS_ADT1, WINDSHIELD]

现在我正在尝试获取一个特定名称的文件夹的计数,这意味着如果我使用模式匹配器查找 CAR_COMPONENTS_ADT,如果我查找 NUTS,它应该将我计数为 2使用模式匹配器,我应该得到一个计数 1

现在我使用以下代码将此文件列表与以下代码中的某些模式进行匹配

 int count=0;
 Pattern pattern = Pattern.compile(patternName);

for(File f: fileList){
Matcher matcher = pattern.matcher(f.getName());
if(matcher.find()){
        count++;
    }
}

现在在正常情况下这工作正常,假设 patternName = "BIRD",它不会与

的文件列表和最终值匹配
 count will be 0

但如果 patternName = "CAR_COMPONENTS",则结果为

  count as 2

所以我不明白的是模式匹配器如何匹配 "CAR_COMPONENTS" 与 "CAR_COMPONENTS_ADT" 和 "CAR_COMPONENTS_ADT1"。尽管它是一个子字符串,但我正在寻找完全匹配而不是部分匹配。

非常欢迎提出建议和改进。提前致谢

这里有两个问题:

  1. Pattern.matcher 的正则表达式不会查找完整的字符串,除非您添加前导 ^(正则表达式的开头)和尾随 $(正则表达式的结尾)。
  2. file.getName() 将 return 包含文件扩展名的名称。

所以,有两种可能的解决方案:

1) 您可以更改模式的正则表达式,以便匹配只匹配完整的文件名:

int count=0;
Pattern pattern = Pattern.compile("^" + patternName + "\.?.+$");
for(File f: fileList){
  Matcher matcher = pattern.matcher(f.getName());
  if(matcher.find()){
    count++;
  }
}

正则表达式的简短说明:

^NUTS\.?.+$
^          $    # Start and end of the regex, to match the entire file-name
 NUTS           # The file name you want to check
     \.?.*     # An (optional) file extension (i.e. `.txt`)

2) 您可以删除扩展名,并使用 .equals:

int count=0;
for(File f: fileList){
  String fileNameWithoutExtension = f.getName().split("\.")[0];
  if(patternName.equals(fileNameWithoutExtension)){
    count++;
  }
}

您只想匹配未包含在 letters/underscore 中的术语。

使用

int count=0;
Pattern pattern = Pattern.compile("(?<![_\p{L}])" + patternName + "(?![_\p{L}])");
for(File f: fileList) {
    Matcher matcher = pattern.matcher(f.getName());
    if(matcher.find()){
        count++;
    }
}

参见regex demo with CAR_COMPONENTS_ADT and a regex demo with CAR_COMPONENTS

(?<![_\p{L}]) 是一个负向后视,它匹配字符串中没有紧跟 _ 或任何字母(将 \p{L} 替换为 [A-Za-z]\p{Alpha} 仅匹配 ASCII 字母),而 (?![_\p{L}]) 是一个否定前瞻,如果当前位置右侧有一个字母或 _,则匹配失败。