Как удалить соответствующие кавычки, когда кавычки окружают слово, начинающееся с: или # (регулярное выражение) - PullRequest
1 голос
/ 16 июня 2019

Если этот шаблон обнаружен внутри строки:

Двойная кавычка (# или: символ) остаток слова, заканчивается двойной кавычкой

Я бы хотел удалить двойные кавычки из матча

Вот пример

"#sql/inline"

до

#sql/inline

или

":username"

до

:username

но "test" останется "test"

Похоже, это делает то, что я ищу, при условии, что в слове нет \ символов

(clojure.string/replace example-string #"(\")(#|:)(.*?)(\")" "$2$3")

Ответы [ 5 ]

6 голосов
/ 16 июня 2019

Регулярное выражение для этого может быть

\"([#:][^\"]*)\"

Заменить на $1.Смотрите regex demo и regex graph :

enter image description here

Команда закрытия:

(clojure.string/replace example-string #"\"([#:][^\"]*)\"" "$1")

Regex детали

  • \" - двойная кавычка
  • ([#:][^\"]*) - Группа захвата # 1:
    • [#:] - # или : char
    • [^\"]* - 0 или более символов, кроме двойных кавычек
  • \" - двойнойкавычка.
2 голосов
/ 16 июня 2019

Или, если у нас могут быть лишние пробелы в нашем ", это выражение удалит эти:

"\s*([#:].+?)\s*"

и наши желаемые данные находятся в этой группе захвата: ([#:].+?).

Демо

Наш код может выглядеть следующим образом:

(clojure.string/replace example-string #"\"\s*([#:].+?)\s*\"" "$1")
1 голос
/ 17 июня 2019

Уже есть несколько хороших ответов на регулярные выражения, но вам не нужно регулярное выражение, чтобы сделать это в Clojure:

(defn remove-quote-wrapper [s]
  (if (and (or (cs/starts-with? s "\"#")
               (cs/starts-with? s "\":"))
           (cs/ends-with? s "\""))
    (subs s 1 (dec (count s)))
    s))

Если вас интересует производительность, этот подход примерно в 4 раза быстрее, чем clojure.string/replace с регулярным выражением.

1 голос
/ 16 июня 2019

Похоже, это делает то, что я ищу, предполагая, что в слове нет \ символов

(clojure.string/replace example-string #"(\")(#|:)(.*?)(\")" "$2$3")

0 голосов
/ 17 июня 2019

Одна проблема с предлагаемыми решениями состоит в том, что они не распознают правильно цитируемые части в тексте.

Давайте назовем цитируемые части, начинающиеся с # или :, «специальными», а остальные"non-special".

Например, в тексте "a"#b"c", "#b" распознается как особая часть и создается "a#bc", тогда как "a" и "c" должны распознаватьсякак не специальные части, а текст следует оставить без изменений.

Другая проблема заключается в том, что экранирование " и \ внутри указанных частей не обрабатывается.

Одно из возможных решений, котороеучитывает следующие проблемы:

(defn remove-quotes [s]
  (clojure.string/replace s
    #"\"([#:]?)(?:([^\"\\]+)|\\([\"\\]))*\""
    #(if (empty? (second %)) (first %) (apply str (rest %)))))

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

После прочтения ответа Тейлора Вуда, который касается только ограниченного случая, я решил добавить нет-regex решение (которое не обрабатывает выход):

(defn remove-quotes [s]
  (loop [processed "" remaining s]
    (if-let [i (clojure.string/index-of remaining \u0022)]
      (let [j (clojure.string/index-of remaining \u0022 (inc i))]
        (recur
          (str processed
               (subs remaining 0 i)
               (apply subs remaining
                      (if (#{\# \:} (get remaining (inc i)))
                        [(inc i) j]
                        [i (inc j)])))
          (subs remaining (inc j))))
      (str processed remaining))))

\u0022 - это просто \".Последний портит внешний вид кода в переполнении стека.

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