2015-04-16 2 views
6

Я играл с этим регулярным выражением в Java для возрастов и не может заставить его работать:Java Regex заменить все не заменяя все слова

(?:^|)(?:the|and|at|in|or|on|off|all|beside|under|over|next)(?: |$) 

Следующие:

pattern.matcher("the cat in the hat").replaceAll(" ") 

дает me cat the hat. Другой пример ввода - the cat in of the next hat, который дает мне cat of next hat.

Есть ли способ сделать эту работу по замене регулярных выражений без необходимости разбивать их на несколько отдельных регулярных выражений для каждого слова и пытаться заменить строку повторно?

ответ

10

Да, вы можете сделать это довольно легко вам просто нужно использовать boundaries, который является то, что вы пытаетесь описать: (?:^|) Просто сделай это вместо:

\b(?:the|and|at|in|or|on|off|all|beside|under|over|next)\b 

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

\b(the|and|at|in|or|on|off|all|beside|under|over|next)\b 
+0

Вам также могут потребоваться сопоставляемые группы: '(\ b (?: the | and | at | in | or | on | off | all | near | under | over | next) \ b) ' – frhd

+1

@frhd Лучшим решением было бы просто заменить группу, не захватывающую захват, : '\ b (the | и | at | in | или | on | off | all | рядом | under | over | next) \ b' – sp00m

+0

@ sp00m yep, этот ответ должен быть обновлен с вашим исправлением. – frhd

5

проблема с вашими в том, что начальные и конечные пробелы включены в совпадений и char cann можно найти в двух матчах.

Так с входными the_cat_in_the_hat (подчеркивание заменить пространства здесь, чтобы сделать объяснение понятнее):

  1. Первый матч: the_, остальные строки: cat_in_the_hat
  2. Второй матч: _in_, остальные строки: the_hat
  3. the не соответствует, поскольку ему не предшествует пробел или начало (оригинальная) строка.

Вы могли бы использовать lookarounds вместо этого, так как они ведут себя, как условия (т.е. if):

(?<=^|)(?:the|and|at|in|or|on|off|all|beside|under|over|next)(?= |$) 

Regular expression visualization

Debuggex Demo

Таким образом, вы бы:

  1. Первый матч: the, остальные строки: _cat_in_the_hat
  2. Второй матч: in, остальные строки: _the_hat
  3. Третий матч: the, остальные строки: _hat

Но @JonathanMee answer является лучшим решением, так как слово границы были реализованы для этой цели точно);

+1

Это отличное описание проблемы, я предпочитаю свое окончательное решение, но +1, потому что это дает лучший ответ. –

+2

Nice , если бы я мог принять два ответа, я бы хотел! – RTF

Смежные вопросы