Regex захватывает взгляд назад и вперед

Я пытаюсь написать регулярное выражение для следующих ситуаций:

badword%
%badword
%badword%

% знаки различаются в зависимости от того, где они находятся. % впереди нужен взгляд сзади, чтобы соответствовать буквам, предшествующим слову badword пока не дойдет до не буквы. Аналогично, любой % то, что не находится впереди, нуждается в заглядывании, чтобы соответствовать буквам после слова badword пока не попадет в не письмо.

Вот чего я пытаюсь достичь. Если у меня есть следующее:

Просто обычное супербедрационное предложение.

badword   # should match "badword", easy enough
badword%  # should match "badwording"
%badword% # should match "superbadwording"

В то же время. Если у меня есть подобное предложение:

Вот еще один пример очень смелого слова.

badword   # should match "badword", easy enough
badword%  # should also match "badword"
%badword% # should match "verybadword"

Я не хочу использовать пробелы в качестве групп захвата утверждений. Предположим, что я хочу захватить \w,

Вот что у меня есть на Java:

String badword  = "%badword%";
String _badword = badword.replace("%", "");
badword = badword.replaceAll("^(?!%)%", "(?=\w)"); // match a % NOT at the beginning of a string, replace with look ahead that captures \w, not working
badword = badword.replaceAll("^%", "(?!=\w)"); // match a % at the beginning of a string, replace it with a look behind that captures \w, not working
System.out.println(badword); // ????

Итак, как я могу это сделать?

PS: пожалуйста, не принимайте %Вынуждены к началу и концу матча. Если % является первым персонажем, тогда ему нужно будет оглянуться назад, любой другой %Смотри вперед.

2 ответа

Решение

Судя по вашему вопросу, нет необходимости использовать lookaround, так что вы можете просто заменить все % с \w*

Snippet:

String tested = "Just a regular superbadwording sentece.";
String bad = "%badword%";
bad = bad.replaceAll("%", "\\\\w*");
Pattern p = Pattern.compile(bad);
Matcher m = p.matcher(tested);
while(m.find()) {
    String found = m.group();
    System.out.println(found);
}

\ w не соответствует #,- и т. д. поэтому я думаю, что \S лучше здесь

badword = badword.replaceAll("^%", "(?!=\w)"); 
// match a % at the beginning of a string, replace it with a look behind 
//that captures \w, not working

(?!=\w) это негативный взгляд на будущее =\w, но кажется, что вы хотите позитивный взгляд. Во-вторых, взгляды и взгляды являются атомарными и, следовательно, по своей сути не захватывают, поэтому, если я прав в моей интерпретации, вы хотите:

"(?<=(\\w+))", Вам нужно дополнительное () для захвата. Для вашей первой части это будет: "(?=(\\w+))и первый аргумент должен быть "(?<!^)%",

PS: вам нужны две обратные косые черты для \\w, а вы, похоже, хотите сопоставить несколько символов, нет? Если это так, вам нужно \\w+, Кроме того, если вы не хотите делать это для каждого случая, я предлагаю использовать String.format() вместо replaceAll(),

Другие вопросы по тегам