Как заключить все группы в скобки * в строку - PullRequest
0 голосов
/ 15 апреля 2020

Я пытался заставить строку replaceAll работать в Java, которая изначально была из блока кода JavaScript. У меня есть следующее

String regexSearch = "((?!([ \\*]))|^)\\[[A-Za-z0-9\\s]*\\](?!\\*)"; //Java Version must escape special characters again
String regexReplacement = "*$&*";

String inputString = "This is a User, [USER 1], and a second user [USER 2]";

Pattern p = Pattern.compile(regexSearch);

Matcher m = p.matcher(inputString);
System.out.println(m.replaceAll(regexReplacement));

Мой желаемый вывод -

This is a User, *[USER 1]*, and a second user *[USER 2]*

Я продолжаю получать недопустимые ошибки ссылки на группу.

Требования следующие. Любой текст, заключенный в квадратные скобки «[» и «]», будет заключен в «*», но при этом он останется в скобках. Однако если в тексте в квадратных скобках есть "|" символ, то это не будет применяться.

Ответы [ 5 ]

1 голос
/ 16 апреля 2020

Ваше первоначальное регулярное выражение ((?!([ \*]))|^)\[[A-Za-z0-9\s]*\](?!\*) пытается (но не может) сопоставить строки [...], если они не заключены в символы *. В Java вы бы записали его как

(?<!\*)\[[A-Za-z0-9\s]*](?!\*)
String regexSearch = "(?<!\\*)\[[A-Za-z0-9\\s]*](?!\\*)";

Однако вы можете использовать более мягкое выражение, например

String regexSearch = "\\[[^\\]\\[|]*]";

Или, если вам нужно сохранить исходное поведение, чтобы оно не сработало совпадения внутри звездочек:

String regexSearch = "(?<!\\*)\\[[^\\]\\[|]*](?!\\*)";

См. демонстрацию regex .

Совпадения:

  • (?<!\*) - отрицательный взгляд сзади которая не соответствует, если слева от текущего местоположения есть * символ
  • \[ - [ символ
  • [^\]\[|]* - 0 или более символов другого типа чем [, ] и |
  • ] - ] char
  • (?!\*) - отрицательный прогноз, который не дает совпадения при наличии * char непосредственно справа от текущего местоположения.

Таким образом, он будет совпадать с [ до ближайшего ] без сопоставления с другими [ и | внутри, т.е. будет соответствовать внутренняя подстрок в квадратных скобках. Это также позволит использовать любые другие специальные и невидимые символы в скобках, такие как дефисы, апострофы и т. Д. c. [A-Za-z0-9\s] разрешены только ASCII буквы, цифры и пробелы.

Java demo :

String regexSearch = "\\[[^\\]\\[|]*]";
String regexReplacement = "*$0*";
String inputString = "This is a User, [USER 1], and a second user [USER 2] not [USER | 3]";
Pattern p = Pattern.compile(regexSearch);
Matcher m = p.matcher(inputString);
System.out.println(m.replaceAll(regexReplacement));
// => This is a User, *[USER 1]*, and a second user *[USER 2]* not [USER | 3]
1 голос
/ 15 апреля 2020

Это можно сделать так просто:

String s = inputString.replaceAll("\\[.*?]", "*$0*")

Группы захвата не нужны.

Результат

This is a User, *[USER 1]*, and a second user *[USER 2]*

Объяснение

\\[     Match '[', escaped since '[' has special meaning, double-escaped because of Java
.*?     Match any text on single line, match as little as possible
]       Match ']', no need to escape since it's not in a character class
*       Literal '*'
$0      Entire matched text '[XXX]'
*       Literal '*'
1 голос
/ 15 апреля 2020

Вам не нужно беспокоиться о сопоставлении всей строки, достаточно следующего:

\[(.*?)\]

Замените это на *[$1]*.

Вот демонстрация по RegExr.

Дальнейшее объяснение: взяв каждый элемент в регулярном выражении по очереди:

  • \[ - нам нужно экранировать открывающую квадратную скобку, потому что квадратные скобки являются зарезервированными символ в регулярных выражениях.
  • (.*?) - .*? соответствует нулю или более любого символа lazily . Это заключено в скобки, чтобы указать, что это группа захвата .
  • ] - закрыть квадратную скобку.

Затем мы заменим это на звездочку за ним следует открывающая квадратная скобка *[, первая группа захвата $1, затем закрывающая квадратная скобка и еще одна звездочка. ]*.

1 голос
/ 15 апреля 2020

Это должно быть сделано.

  • String.replaceAll - первый аргумент - регулярное выражение.
  • Второй аргумент - строка замены. $1 - это группа захвата.
String regexSearch = "\\[.*?]";     
String inputString = "This is a User, [USER 1], and a second user [USER 2]";
inputString = inputString.replaceAll(regexSearch, "*$1*");
System.out.println(inputString);

Отпечатки

This is a User, *[USER 1]*, and a second user *[USER 2]*

0 голосов
/ 15 апреля 2020

Попробуйте заменить все [ на - *[* и проделайте то же самое для ], используя строковый метод .replace(oldChar, newChar) в java.

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