在 Java 中使用文件名和扩展名清理字符串

Avi*_*ión 5 java regex string

有这四种类型的文件名:

  1. 带有双扩展名的文件名
  2. 没有扩展名的文件名
  3. 文件名末尾带点,无扩展名
  4. 具有正确名称的文件名。

像这样:

String doubleexsension = "doubleexsension.pdf.pdf";
String noextension = "noextension";
String nameWithDot = "nameWithDot.";
String properName = "properName.pdf";

String extension = "pdf";
Run Code Online (Sandbox Code Playgroud)

我的目标是清理所有类型并仅filename.filetype正确输出。为了发表这篇文章,我做了一个愚蠢的脚本:

ArrayList<String> app = new ArrayList<String>();
app.add(doubleexsension);
app.add(properName);
app.add(noextension);
app.add(nameWithDot);

System.out.println("------------");

for(String i : app) {

    // Ends with .
    if (i.endsWith(".")) {
        String m = i + extension;
        System.out.println(m);
        break;
    }

    // Double extension
    String p = i.replaceAll("(\\.\\w+)\\1+$", "$1");
    System.out.println(p);
}
Run Code Online (Sandbox Code Playgroud)

这输出:

------------
doubleexsension.pdf
properName.pdf
noextension
nameWithDot.pdf
Run Code Online (Sandbox Code Playgroud)

我不知道我该如何处理noextension。我该怎么做?当没有扩展名时,它应该采用该extension值并将其附加到字符串的末尾。

我想要的输出是:

------------
doubleexsension.pdf
properName.pdf
noextension.pdf
nameWithDot.pdf
Run Code Online (Sandbox Code Playgroud)

提前致谢。

Wik*_*żew 4

您可以添加正则表达式的替代方案以匹配各种场景:

(?:(\.\w+)\1*|\.|([^.]))$
Run Code Online (Sandbox Code Playgroud)

并替换为$2.pdf. 请参阅正则表达式演示

编辑:如果已知可以复制的扩展名,您可以通过交替组使用白名单方法:

(?:(\.(?:pdf|gif|jpe?g))\1*|\.|([^.]))$
Run Code Online (Sandbox Code Playgroud)

请参阅另一个正则表达式演示

细节

  • (?:- 分组开始,$字符串锚点的末尾应用于下面的所有替代项(它们必须位于字符串的末尾)
    • (\.\w+)\1*- 重复(或不)扩展名(.+ 1+ 个单词字符重复零次或多次)(使用白名单方法,仅考虑指定的扩展名 -如果添加更多替代项,(?:pdf|gif|jpe?g)则仅匹配pdf, gif, jpeg等), jpg
    • |- 或者
    • \.- 一个点
    • |- 或者
    • ([^.])- 任何不是捕获到组 2 中的点的字符
  • )- 外层分组结束
  • $- 字符串末尾。

请参阅 Java 演示

List<String> strs = Arrays.asList("doubleexsension.pdf.pdf","noextension","nameWithDot.","properName.pdf");
for (String str : strs)
    System.out.println(str.replaceAll("(?:(\\.\\w+)\\1*|\\.|([^.]))$", "$2.pdf"));
Run Code Online (Sandbox Code Playgroud)

  • 也许您想从扩展名中排除“_”?如果您知道其中不能有“_”,请使用“(?:(\.[a-zA-Z0-9]+)\1*|\.|([^.]))$”(或`(?:(\.\p{Alnum}+)\1*|\.|([^.]))$`)。否则,您需要在交替组中列出列入白名单的扩展程序 - [`(?:(\.(?:pdf|gif|jpe?g))\1*|\.|([^.]))$ `](https://regex101.com/r/ftAncS/3) (2认同)