Regex: сопоставить все дефисы и заменить пробелами слова, содержащие только буквы AND, которые НЕ находятся в кавычках - PullRequest
0 голосов
/ 23 ноября 2018

Это регулярное выражение: \b([A-z*]+)-(?=[A-z*]+\b)

с этой заменой: $1

Применено:

Jean-Pierre bought "blue-green-red" product-2345 and other blue-red stuff.

Дает мне:

Jean Pierre bought "blue green red" product-2345 and other blue red stuff.

Пока я хочу:

Jean Pierre bought "blue-green-red" product-2345 and other blue red stuff.

https://regex101.com/r/SJzAaP/1

РЕДАКТИРОВАТЬ:

Я использую Clojure (Java)

РЕДАКТИРОВАТЬ 2:

yellow-black-white -> yellow black white

product_a-b -> product_a-b

РЕДАКТ. 3: Принятый ответ переведен на Clojure

(clojure.string/replace
 "Jean-Pierre bought \"blue-green-red\" product-2345 and other blue-red-green stuff yellow-black-white product_a-b"
 #"(\"[^\"]*\")|\b([a-zA-Z]+)-(?=[a-zA-Z]+\b)"
 (fn [[s1 s2 s3]] (if s2 s1 (str s3 " "))))

;;=> "Jean Pierre bought \"blue-green-red\" product-2345 and other blue red green stuff yellow black white product_a-b"

Ответы [ 3 ]

0 голосов
/ 23 ноября 2018

В Java вы можете использовать что-то вроде

String s = "Jean-Pierre bought \"blue-green-red\" product-2345 and other blue-red stuff. yellow-black-white. product_a-b";
StringBuffer result = new StringBuffer();
Matcher m = Pattern.compile("(\"[^\"]*\")|\\b([a-zA-Z]+)-(?=[a-zA-Z]+\\b)").matcher(s);
while (m.find()) {
    if (m.group(1) != null) {
        m.appendReplacement(result, m.group(0));
    } else {
        m.appendReplacement(result, m.group(2) + " ");
    }
}
m.appendTail(result);
System.out.println(result.toString());
// => Jean Pierre bought "blue-green-red" product-2345 and other blue red stuff. yellow black white. product_a-b

См. Демо Java .

Регулярное выражение:

("[^"]*")|\b([a-zA-Z]+)-(?=[a-zA-Z]+\b)

Подробности

  • ("[^"]*") - Группа 1: ", 0+ символов, отличных от " и "
  • | - или
  • \b - граница слова - ([a-zA-Z]+) - группа 2: 1+ букв (может быть заменена на (\p{L}+) для соответствия любой букве)
  • - - дефис
  • (?=[a-zA-Z]+\b) - положительный прогноз, который, непосредственно справа от текущего местоположения, требует 1+ букв и границы слова.

Если группа 1 соответствует (if (m.group(1) != null)), вы простовставить матч обратно в результат.Если нет, вставьте обратно значение группы 2 и пробел.

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

(def s "Jean-Pierre bought \"blue-green-red\" product-2345 and other blue-red stuff. yellow-black-white. product_a-b"

(defn append [[g1 g2 g3]] (if g2 g1 (str g3 " ")))

(clojure.string/replace s #"(\"[^\"]*\")|\b([a-zA-Z]+)-(?=[a-zA-Z]+\b)" append)

;;=> "Jean Pierre bought \"blue-green-red\" product-2345 and other blue red stuff. yellow black white. product_a-b"
0 голосов
/ 24 ноября 2018

Попробуйте это

(".*?")|((?<group>\b([A-z*]+))-)

с заменой

${group} $1

Вы можете проверить это здесь

0 голосов
/ 23 ноября 2018

Это должно работать, если вам не нужно обрабатывать слишком сложные случаи:

(?: |^)\w+(-)(?![0-9])\w+

Это соответствует любому экземпляру word(hyphen)word, в начале которого есть пробел илиначало строки (поэтому содержимое в кавычках не будет совпадать, потому что перед ним будет кавычка, а не пробел или начало строки).

Дайте мне знать, если это не такработать для вас. Живая демоверсия .

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