【问题标题】:Java Pattern Matcher Incorrectly matches sub stringJava 模式匹配器不正确地匹配子字符串
【发布时间】:2018-06-14 12:08:49
【问题描述】:

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

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

现在我正在尝试获取一个特定名称的文件夹的计数,这意味着如果我使用模式匹配器查找 CAR_COMPONENTS_ADT,它应该给我计数为 2,如果我使用模式匹配器查找 NUTS,我应该计数为 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”匹配。即使它是一个子字符串,但我正在寻找完全匹配而不是部分匹配。

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

【问题讨论】:

  • 在正则表达式的开头使用^,在结尾使用$:^CAR_COMPONENTS_ADT$
  • 这是否意味着只有在搜索词未包含字母或/和_ 时才需要匹配?试试pattern.matcher("(?<![_\\p{L}])" + f.getName() + "(?![_\\p{L}])")
  • 会做,我也试过这个似乎有效
  • for(File f: fileList){ if(patternName.equals(f){ for(File t:fileList){ Matcher matcher = p.matcher(t) if(matcher.find(){计数++} } }}
  • 哦,对不起,我把代码弄乱了一点,然后我会发布答案。

标签: java regex pattern-matching matcher


【解决方案1】:

您只想匹配不包含字母/下划线的术语。

使用

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 和a regex demo with CAR_COMPONENTS。

(?&lt;![_\p{L}]) 是一个否定的lookbehind,它匹配字符串中的位置,该位置没有紧跟在_ 或任何字母之前(将\p{L} 替换为[A-Za-z] 或\p{Alpha} 以仅匹配ASCII 字母)和(?![_\p{L}]) 是一个否定的前瞻,如果当前位置右侧有一个字母或 _,则匹配失败。

【讨论】:

  • @Sid 很高兴它对你有用。如果我的回答对您有帮助(请参阅How to upvote on Stack Overflow?),也请考虑投票,因为您在达到 15 个代表点后有权获得投票特权。
【解决方案2】:

这里有两个问题:

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

因此,有两种可能的解决方案:

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++;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    相关资源
    最近更新 更多