Java: заменить () разделитель канала n, начинающийся с конца на регулярное выражение - PullRequest
1 голос
/ 23 апреля 2019

я пытаюсь заменить первый "|"но начиная с конца строки:

usr/bin/pipe|pipe|name|28|-rwxr-xr-x|root:root||46711b361edd4512814d9b367ae765f42a71d729708b3f2e162acb8f64592610|

мое имя файла pipe|pipe|name, и я хочу, чтобы мое регулярное выражение вернуло меня usr/bin/pipe|pipe|name

Я начал с этого регулярного выражения: .([^\|]*)$ но я не знаю, как идти дальше в трубах: https://regex101.com/r/ttbiab/3

И на Java:

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

Ответы [ 3 ]

0 голосов
/ 23 апреля 2019

Если до конца строки имеется фиксированное количество из 6 каналов, и вы хотите выбрать отдельные каналы до этого, чтобы заменить их, вы можете использовать \G, чтобы подтвердить положение в предыдущем совпадении ииспользуйте предположение, чтобы утверждать, что справа 6 раз не труба, за которой следует труба.

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

В Java:

String regex = "(?:([^\\|]*)|\\G(?!^))\\|([^|]*)(?=(?:[^|]*\\|){6})";
  • (?: Негруппа захвата
    • ([^\|]*) Захват в группе 1, соответствующий не трубе 0+ раз, с использованием отрицательного класса символов
    • | ИЛИ
    • \G(?!^) Подтвердить позицию в конце предыдущего матча, а не в начале
  • ) Закрыть группу без захвата
  • \|([^|]*) Совместить трубу и захватить вгруппа 2 соответствует 0+ раз, а не трубе
  • (?= группа без захвата
    • (?:[^|]*\|){6} Позитивный взгляд, утверждаем, что справа 6 раз не труба, за которой следует труба
  • ) Закрыть группу без захвата

Regex demo | Java demo

Если вы хотите заменить канал, например, #, используйте 2 группы захвата:

$1#$2
0 голосов
/ 23 апреля 2019

Судя по вашим комментариям, вы не знаете, сколько каналов будет в имени файла, но вы делаете знаете, сколько каналов во входной строке, которых нет в имени файла.В этом случае регулярное выражение может быть не лучшим подходом.Есть несколько различных способов сделать это, но, возможно, один из самых простых для понимания и поддержки будет разделить строку, а затем рекомбинировать ее с заменами, где это применимо:

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);

Приведенные выше примерылюбое количество каналов, довольно настраиваемо, и (на мой взгляд) намного легче понять и отладить, чем пытаться использовать регулярные выражения.

0 голосов
/ 23 апреля 2019

Вы можете попробовать что-то вроде этого [\|]([^\|]*[\|]){5}$. Он соответствует количеству труб, равному 5, за которым следует первая труба с концов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...