3

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

text.txt、temp_doc.doc、template.tmpl、empty.zip

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

  1. 只显示文件名而不是它们各自的扩展名
  2. 排除以“temp_”开头的文件

它应该看起来像:

文本

模板

空的

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

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

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

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

PS我只研究了几天的正则表达式,所以请不要嘲笑这个新手风格的过于复杂的代码:)

4

3 回答 3

4
  • 只显示文件名而不是它们各自的扩展名
  • 排除以“temp_”开头的文件

一种变体是这样的:

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

这允许

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

但实际上,这真的很复杂。您最好编写一个小函数,以逗号分隔输入并从部分中删除扩展名。

无论如何,这是拆解:

(?:^|,) # 文件名开始:字符串或逗号的开始
(?!temp_) # 否定前瞻:不允许以“temp_”开头的文件名
( # match group 1 (将包含你的文件名)
  (?: # 非捕获组(匹配一个允许的字符)
    (?! # 负前瞻 (不跟在后面):
      \。# 一个点
      [^.]* # 任意数量的非点(这与扩展名匹配)
      (?:,|$) # 文件名结束(字符串或逗号结尾)
    ) # 结束负前瞻
    . # 这个字符有效,匹配它
  )+ # 结束非捕获组,重复
) # 结束组 1

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

于 2012-08-05T14:49:53.697 回答
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);

这也允许文件名中包含点。

于 2012-08-05T14:47:19.603 回答
3

另外一个选项:

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

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

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

你可以在这里看到一个例子:http ://www.rubular.com/r/QywiDgFxww

于 2012-08-05T14:52:26.737 回答