在java中从字符串列表中提取公共前缀

在java中从字符串列表中提取公共前缀,java,regex,Java,Regex,我想在java中做类似的事情。其中字符串列表是文件路径 如: List filePaths1=新阵列列表; filePaths1.add/root/test1/asas; 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/

我想在java中做类似的事情。其中字符串列表是文件路径 如: List filePaths1=新阵列列表; filePaths1.add/root/test1/asas; 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/; 文件路径1.add/root/rahul/e?ee/asasa/; filePaths1.add/root/rahul/asasa/; 文件路径1.add/root/rahul/no*ttthis/asasa/**; filePaths1.add/etc/rahul/test;

想要实现一个函数,如果我们将上面的列表传递给它,它将返回以下字符串的列表

{/root/test1,/root/test,/root/rahul,/etc/rahul/test}

在上述情况下,它应该将每个字符串与另一个字符串进行比较 如果我们考虑2个字符串/root /test1/asas//root /test1,它具有最长的公共前缀为/root /test1,因此我们将把它添加到输出列表中,如果有任何从/root / test1开始的字符串,它将由/root / Test1表示。 它旁边有五个以/root/test开头的字符串,输出列表将包含/root/test,因为这五个字符串的公共前缀最长为/root/test

同样,只有1个字符串具有模式/etc/rahul/test,该模式不共享或以定义的任何其他模式开头,因此将按原样添加该模式

我们可以用正则表达式来实现吗?任何建议都会很有帮助。如果需要任何其他信息,请告诉我。

说明 如果我理解正确,您正在寻找一种方法来确定列表中每个文件夹的最大公分母。我看到您提供了一个大的文件夹列表,您希望筛选所有条目并只返回最大的条目。该附加处理逻辑超出了此表达式的范围

因此:

/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
描述 在查看详细的聊天窗口后,我发现您有来自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不是通用前缀?为什么不/你提到的所有字符串的公共前缀是什么?请详细解释您对常用前缀的定义。@RahulBorkar:在您的示例中,/etc/rahul为什么是通用前缀?只有一次。对不起,这对我来说毫无意义。再次使用参数,/etc/rahul/test和/root/rahul/e?ee/asasa/也有一个共同的前缀:/。实际上,/是所有输入中最长的公共前缀。主要问题是:没有人理解规则,为什么这个输入会导致那个输出。只要这还不清楚,没有人会试图回答这个问题。@RahulBorkar:仍然很不清楚。在您的新示例中,/root/test是/root/test1的前缀,那么为什么两者都应该在结果列表中呢?它应该返回/root/test1
/root/test1/
/root/test1
/root/test
/root/test/
/root/rahul/
/etc/rahul/