Java中的正则表达式外观构造:建议所需的优化

时间:2012-08-05 14:34:00

标签: java regex lookahead negative-lookahead

我正在尝试在以逗号分隔的列表中搜索文件名:

  

的text.txt,temp_doc.doc,template.tmpl,empty.zip

我使用Java的正则表达式实现。输出要求如下:

  1. 仅显示文件名,而不显示各自的扩展名
  2. 排除以“temp _”
  3. 开头的文件

    应该看起来像:

      

    文本

         

    模板

         

    到目前为止,我已设法编写或多或少令人满意的正则表达式来应对第一项任务:

    [^\\.,]++(?=\\.[^,]*+,?+)
    

    我相信它符合第二个要求最佳选择是使用外观构造,但不确定如何编写可靠和优化的表达式。虽然以下正则表达式似乎确实做了所需要的,但如果没有其他原因,它显然是一个有缺陷的解决方案,而不是依赖于显式的最大文件名长度。

    (?!temp_|emp_|mp_|p_|_)(?<!temp_\\w{0,50})[^\\.,]++(?=\\.[^,]*+,?+)
    

    P.S。我一直在研究正则表达几天,所以请不要嘲笑这个新手式的过于复杂的代码:)

3 个答案:

答案 0 :(得分:4)

  
      
  • 仅显示文件名,而不显示各自的扩展名
  •   
  • 排除以“temp _”
  • 开头的文件   

一个变体是这样的:

(?:^|,)(?!temp_)((?:(?!\.[^.]*(?:,|$)).)+)

这允许

  • 不以“单词字符”开头的文件名(Tim Pietzcker的解决方案没有)
  • 包含点的文件名(类似于file.name.ext的文件名将与file.name匹配)

但实际上,这真的很复杂。你最好写一个小函数,用逗号分隔输入并从部分中剥离扩展。

无论如何,这是拆解:

(?:^|,)        # filename start: either start of the string or comma
(?!temp_)      # negative look-ahead: disallow filenames starting with "temp_"
(              # match group 1 (will contain your file name)
  (?:          #   non-capturing group (matches one allowed character)
    (?!        #     negative look-ahead (not followed by):
      \.       #       a dot
      [^.]*    #       any number of non-dots (this matches the extension)
      (?:,|$)  #       filename-end (either end of string or comma)
    )          #     end negative look-ahead
    .          #     this character is valid, match it
  )+           #   end non-capturing group, repeat
)              # end group 1

http://rubular.com/r/4jeHhsDuJG

答案 1 :(得分:3)

这个怎么样:

Pattern regex = Pattern.compile(
    "\\b        # Start at word boundary\n" +
    "(?!temp_)  # Exclude words starting with temp_\n" +
    "[^,]+      # Match one or more characters except comma\n" +
    "(?=\\.)    # until the last available dot", 
    Pattern.COMMENTS);

这也允许文件名中的点。

答案 2 :(得分:3)

另一种选择:

(?:temp_[^,.]*|([^,.]*))\.[^,]*

该模式将匹配所有文件名,但捕获有效名称。

  • 如果在当前位置,该模式可以与temp_file.ext匹配,则匹配它并且不会捕获。
  • 它无法与temp_匹配,它会与([^,.]*)\.[^,]*匹配,并捕获文件的名称。

您可以在此处查看示例:http://www.rubular.com/r/QywiDgFxww