Java:replace()以正则表达式结尾的n管道分隔符

Java:replace()以正则表达式结尾的n管道分隔符,java,regex,string,Java,Regex,String,我试图替换第一个“|”,但从字符串末尾开始: usr/bin/pipe|pipe|name|28|-rwxr-xr-x|root:root||46711b361edd4512814d9b367ae765f42a71d729708b3f2e162acb8f64592610| 我的文件名是pipe | pipe | name,我希望我的正则表达式返回我usr/bin/pipe | pipe | name 我从这个正则表达式开始:([^\|]*)$,但我不知道如何进一步使用管道: 在Java中: S

我试图替换第一个“|”,但从字符串末尾开始:

usr/bin/pipe|pipe|name|28|-rwxr-xr-x|root:root||46711b361edd4512814d9b367ae765f42a71d729708b3f2e162acb8f64592610|
我的文件名是
pipe | pipe | name
,我希望我的正则表达式返回我
usr/bin/pipe | pipe | name

我从这个正则表达式开始:
([^\|]*)$
,但我不知道如何进一步使用管道:

在Java中:

String strLine = "usr/bin/pipe|pipe|name|28|-rwxr-xr-x|root:root||46711b361edd4512814d9b367ae765f42a71d729708b3f2e162acb8f64592610|";
strLine = strLine.replaceAll(".([^\\|]*)$", "[:124:]");
System.out.println("strLine : " + strLine);

您可以尝试类似以下内容:
[\\\\;]([^\\\\\]*[\\\\\;]]){5}$
。它与管道计数5相匹配,后面是从末端开始的第一根管道。

您可以尝试类似的方法
[\\\\;]([^\\\\\\\\\\]*[\\\\\\\\\]]{5}$
。它与管道计数5相匹配,后面是从末端开始的第一根管道。

如果在管柱末端之前有固定数量的6根管道,并且您希望在此之前选择单个管道以替换它们,您可以使用
\G
来断言上一次匹配时的位置,并使用向前看来断言右侧的位置是管道后面不是管道的6倍

(?:([^\|]*)|\G(?!^))\|([^|]*)(?=(?:[^|]*\|){6})
在Java中:

String regex = "(?:([^\\|]*)|\\G(?!^))\\|([^|]*)(?=(?:[^|]*\\|){6})";
  • (?:
    非捕获组
    • ([^\|]*)
      在组1中捕获与管道不匹配的0+次,使用
    • |
    • \G(?!^)
      在上一个匹配的末尾而不是开始处断言位置
  • 关闭非捕获组
  • \ |([^ |]*)
    匹配一个管道,并在第2组中捕获匹配0+次非管道
  • (?=
    非捕获组
    • (?:[^ |]*\\\|){6}
      正面向前看,断言右边的是6倍,而不是后面跟着管道的管道
  • 关闭非捕获组
|

如果要将管道替换为例如
#
,请使用两个捕获组:

$1#$2

如果在字符串结束之前有固定数量的6个管道,并且您希望选择之前的单个管道来替换它们,则可以使用
\G
来断言上一次匹配的位置,并使用前瞻性来断言右侧的不是后面跟着管道的管道的6倍

(?:([^\|]*)|\G(?!^))\|([^|]*)(?=(?:[^|]*\|){6})
在Java中:

String regex = "(?:([^\\|]*)|\\G(?!^))\\|([^|]*)(?=(?:[^|]*\\|){6})";
  • (?:
    非捕获组
    • ([^\|]*)
      在组1中捕获与管道不匹配的0+次,使用
    • |
    • \G(?!^)
      在上一个匹配的末尾而不是开始处断言位置
  • 关闭非捕获组
  • \ |([^ |]*)
    匹配一个管道,并在第2组中捕获匹配0+次非管道
  • (?=
    非捕获组
    • (?:[^ |]*\\\|){6}
      正面向前看,断言右边的是6倍,而不是后面跟着管道的管道
  • 关闭非捕获组
|

如果要将管道替换为例如
#
,请使用两个捕获组:

$1#$2

根据您的评论,您似乎不知道文件名中有多少管道,但您知道输入字符串中有多少管道不在文件名中。在这种情况下,正则表达式可能不是最好的方法。有几种不同的方法可以做到这一点,但最容易理解和维护的方法之一可能是拆分字符串,然后在适用的情况下使用替换项重新组合它:

String input = "usr/bin/pipe|pipe|name|28|-rwxr-xr-x|root:root||46711b361edd4512814d9b367ae765f42a71d729708b3f2e162acb8f64592610|";
String pipeReplacement = ":124:";
int numberOfPipesToKeep = 7;

String[] split = input.split("\\|");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
    sb.append(split[i]);
    if (i < split.length - numberOfPipesToKeep) {
        sb.append(pipeReplacement);
    } else {
        sb.append("|");
    }
}

String output = sb.toString();
System.out.println(output);
String input=“usr/bin/pipe | pipe | name | 28 |-rwxr-xr-x | root:root | 46711B361ED4512814D9B367AE765F42A71D729708B3F2E162ACB8F64592610 |”;
字符串pipeReplacement=“:124:”;
int numberofpipestokep=7;
String[]split=input.split(“\\\\”);
StringBuilder sb=新的StringBuilder();
对于(int i=0;i

上面的示例可以处理任意数量的管道,非常可配置,并且(在我看来)比尝试使用正则表达式更容易理解和调试。

根据您的评论,您似乎不知道文件名中将包含多少管道,但是您知道输入字符串中有多少管道不在文件名中。在这种情况下,正则表达式可能不是最好的方法。有几种不同的方法可以做到这一点,但最容易理解和维护的方法之一可能是拆分字符串,然后在适用的情况下使用替换项重新组合它:

String input = "usr/bin/pipe|pipe|name|28|-rwxr-xr-x|root:root||46711b361edd4512814d9b367ae765f42a71d729708b3f2e162acb8f64592610|";
String pipeReplacement = ":124:";
int numberOfPipesToKeep = 7;

String[] split = input.split("\\|");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
    sb.append(split[i]);
    if (i < split.length - numberOfPipesToKeep) {
        sb.append(pipeReplacement);
    } else {
        sb.append("|");
    }
}

String output = sb.toString();
System.out.println(output);
String input=“usr/bin/pipe | pipe | name | 28 |-rwxr-xr-x | root:root | 46711B361ED4512814D9B367AE765F42A71D729708B3F2E162ACB8F64592610 |”;
字符串pipeReplacement=“:124:”;
int numberofpipestokep=7;
String[]split=input.split(“\\\\”);
StringBuilder sb=新的StringBuilder();
对于(int i=0;i

上面的示例可以处理任意数量的管道,非常可配置,并且(在我看来)比尝试使用正则表达式更容易理解和调试。

您能提供示例吗?不确定您指的是字符串中的第一个管道还是最后一个管道。是哪个命令生成您要分析的字符串?根据您所展示的内容,从理论上讲,文件名可能不包含管道、一个管道或多个管道,因此您需要使用管道以外的其他内容作为正则表达式的基础。我想使用管道处理文件;)是一个扫描代理给我生成了一个包含我在linux机器上安装的所有软件包的文件你是说这样吗?你能提供一些例子吗?不确定您指的是字符串中的第一个管道还是最后一个管道。是哪个命令生成您要分析的字符串?根据您所展示的,文件名理论上可能不包含管道,