我想在java中做类似的事情(extracting the common prefixes from a list of strings)。字符串列表是文件路径
Eg:
List filePaths1 = new ArrayList();
filePaths1.add("/root/test1/asass");
filePaths1.add("/root/test1");
filePaths1.add("/root/test");
filePaths1.add("/root/test/aaa/");
filePaths1.add("/root/test/bbb/ccc");
filePaths1.add("/root/test/fff/");
filePaths1.add("/root/test/eee/asasa/");
filePaths1.add("/root/rahul/e?ee/asasa/");
filePaths1.add("/root/rahul/asasa/");
filePaths1.add("/root/rahul/no*tthis/asasa/**");
filePaths1.add("/etc/rahul/test");
想要实现一个函数,如果我们将上面的列表传递给它,它将返回以下字符串的列表。
{"/root/test1", "/root/test", "/root/rahul", "/etc/rahul/test"}
它应该将每个字符串与另一个字符串进行比较,在上面的情况 如果我们考虑2个字符串“/ root / test1 / asass”和“/ root / test1”,它有最长的公共前缀为/ root / test1,所以我们将它添加到输出列表,如果有任何其他字符串正在启动使用/ root / test1,它将由/ root / test1表示。
由于有五个字符串以/ root / test开头,因此输出列表将包含/ root / test,因为这5个字符串的最长公共前缀为“/ root / test”。
同样,只有1个字符串具有模式/ etc / rahul / test,它不共享或以定义的任何其他模式开始,因此它将按原样添加,
我们可以使用正则表达式吗?任何建议都会非常有用。如果需要任何其他信息,请告诉我。
答案 0 :(得分:1)
如果我理解正确,您正在寻找一种方法来识别列表中每个文件夹的最大公分母。我看到你提供了一个很大的文件夹列表,你想筛选所有条目,只返回最大的。额外的处理逻辑超出了这个表达式的范围。
所以给出:
/root/test1/aaaaa
/root/test2/bbbbb
/root/test3/ccccc
您希望/root/
成为所有条目的公共文件夹。
鉴于:
/root/test1/aaaaa
/root/test1/bbbbb
/root/test1/ccccc
您希望/root/test1/
成为常用文件夹。
此正则表达式将在上面的示例中找到那些最大的分母。您可以使用它来遍历所有值,匹配它们并根据您所需的逻辑构建结果数组。
^(\/.*(?=[\/\n\r])).*[\r\n]*(?:^(?=\1).*?[\r\n]*)*\Z
注意:我正在使用不区分大小写的选项来保持示例简单,如果在* nix系统上运行,则需要删除它,以区分文件级别的大写和小写。同样使用此表达式需要多行选项,例如:
Pattern re = Pattern.compile("^(\\/.*(?=[\\/\\n\\r])).*[\\r\\n]*(?:^(?=\\1).*?[\\r\\n]*)*\\Z",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
OP中不清楚的是你想如何处理如下列表:
/root/test1/test2/test3/aaaaa
/root/test1/test2/bbbbb
/root/test1/ccccc
答案 1 :(得分:1)
在查看详细的聊天窗口后,我看到你有来自M Buettner的示例文本:
(diverging at level 1)
/root/abc/foo
/etc/def/bar
would give two entries
(diverging at level 2)
/root/abc/foo
/root/def/foo
would give two entries
(diverging at level 3 and beyond)
but
/root/abc/def/ghi
/root/abc/klm/nop
would give only one entry? (/root/abc/)
看起来你想要从字符串的开头到第三个/
这个powershell [抱歉我不太了解java]确实返回了唯一值。
$folders = New-Object System.Collections.ArrayList
$null = $folders.add("/root/test1/asass")
$null = $folders.add("/root/test1")
$null = $folders.add("/root/test")
$null = $folders.add("/root/test/aaa")
$null = $folders.add("/root/test/bbb/ccc")
$null = $folders.add("/root/test/fff")
$null = $folders.add("/root/test/eee")
$null = $folders.add("/root/rahul/e?ee/aaaaa")
$null = $folders.add("/root/rahul/aaa")
$null = $folders.add("/root/rahul/no*tthis/aaaaa")
$null = $folders.add("/root/rahul/test")
$null = $folders.add("/etc/rahul/test")
Write-Host "------"
$Output = New-Object System.Collections.ArrayList
foreach ($folder in $folders) {
[regex]::Match($folder, "^(\/(?:.*?(?:\/|$)){0,2})", "Multiline") | foreach {
# found a match set
$null = $Output.add($_.Groups[1].Value)
} # next match
} # next folder
$Output | select -unique
<强>返回强>
/root/test1/
/root/test1
/root/test
/root/test/
/root/rahul/
/etc/rahul/