Regex для анализа простой уценки с экранированными символами без опозданий - PullRequest
0 голосов
/ 20 января 2019

Примечание: Это должно работать в JavaScript. RegExp

Я должен разобрать строку следующим образом:

yo (p:abc-123-def) meets  \(p:2) \(in the cinema\) \\ (p:3) (p:4\) won't 

Что мне нужноизвлечь все (<entity>:<id>) разметки, но игнорировать экранированные символы, такие как \(in the ciname\) или \\.Из приведенного выше примера регулярное выражение должно соответствовать только

(p:abc-123-def)
(p:3)

, но не \(p:2) или \(p:4), так как скобки экранированы.

Теперь я все еще могу изменить эту разметкутак что, если есть более простой способ сделать все это, я открыт для предложений.В противном случае мне нужно было бы получить эти (<entity>:<id>) разметки от регулярного выражения.

Примерно так

(?<!\\)\([^(?<!\\)\(]*\)

будет работать, но группы наблюдения не поддерживаютсявсе браузеры.

Ответы [ 3 ]

0 голосов
/ 20 января 2019

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

Например:

\\+\([^)]+\)|\([^)]+\\+\)|(\([^:]+:[^:]+\))

Regexдемо

  • \\+\([^)]+\) Соответствует 1+ раз обратной косой черты с последующим открытием ( до )
  • | или
  • \([^)]+\\+\) совпадение ( до 1+ раз обратной косой черты и )
  • | или
  • ( группа захвата
    • \([^:]+:[^:]+\) совпадение (не :, затем : и снова не :, за которым следует )
  • ) Закрыть группу захвата

const regex = /\\+\([^)]+\)|\([^)]+\\+\)|(\([^:]+:[^:]+\))/g;
const str = `yo (p:abc-123-def) meets  \\(p:2) \\(in the cinema\\) \\\\ (p:3) (p:4\\) won't`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (typeof(m[1]) != 'undefined') {
    console.log(m[1]);
  }
}
0 голосов
/ 20 января 2019

Может быть сложным, когда обратные слэши повторяются много раз, например: \\\\\\\\\\\\\\(p:1). Вам нужно знать, является ли количество обратных косых черт четным или нечетным, чтобы узнать, экранирован ли ( или нет.

Во-вторых, двоеточие, встречающееся в скобках, также может быть экранировано и не будет учитываться (?).

Поэтому я бы предложил работать с чем-то вроде (?:\\.|[^:)\\])*, которое имеет дело с экранированными символами (.) и предъявляет некоторые требования к неэкранированным символам, например [^:)\\].

Итак, это результат:

(?<!\\)(?:\\.)*\((?:\\.|[^:)\\])*:(?:\\.|[^:)\\])*\)

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

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

(?:[^\\]|^)((?:\\.)*\((?:\\.|[^:)\\])*:(?:\\.|[^:)\\])*\))

Так что здесь вам нужно поработать с первой захваченной группой.

0 голосов
/ 20 января 2019

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

/(?<!\\)\([a-zA-Z]+\:[0-9a-zA-Z_]+\)/g

Редактировать: Этот код скомпилирован с помощью JavaScript.

Regexpr Fiddle

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