Regex Lookbehind в альтернативах JavaScript - PullRequest
0 голосов
/ 18 января 2019

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

(?<=@[A-Z|a-z]+,)\s|(?<=@[A-Z|a-z]+,\s[A-Z|a-z]+)\s(?=\[[A-Z|a-z]+\])

, что переводится как:

соответствует всем пробелам, которым предшествует:

  • @
  • , за которым следует любое количество символов в диапазоне A-Z или a-z
  • с запятой

ИЛИ

соответствует всем пробелам, которым предшествует:

  • @

  • , за которым следует любое количество символов в диапазоне A-Z или a-z

  • с запятой
  • с пробелом
  • , за которым следует любое количество символов в диапазоне A-Z или a-z

И сменяются:

  • [
  • , за которым следует любое количество символов в диапазоне A-Z или a-z
  • ]

Однако JS не поддерживает просмотр сзади. Есть ли альтернатива для поддержки вышеупомянутого регулярного выражения в JS или любой библиотеке npm, которую я могу использовать вместо?

Так что, если у нас есть предложение вроде
Hi my name is @John, Doe [Example] and I am happy to be here это должно стать
Hi my name is @John,Doe[Example] and I am happy to be here.
Кроме того, если у нас есть что-то вроде
Hi my name is @John, Smith Doe [Example], это должно стать
Hi my name is @John,SmithDoe[Example].

Ответы [ 3 ]

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

Что вам нужно сделать, это преобразовать lookbehinds в группы захвата, чтобы включить их в строку замены (обратите внимание, что установлен регистронезависимый флаг (i)):

(@[a-z]+,)([\t ]*([a-z]+)[\t ]*(?=\[[a-z]+\])|[\t ]+)

Замените на $1$3, если вы хотите удалить эти пробелы.

Смотрите демо здесь

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

Просто обновите версию Node.js. Смотровые утверждения являются частью ECMAScript 2018 и уже реализованы в Chromium и Node.js. Согласно http://kangax.github.io/compat-table/es2016plus/, Chromium 70 и Node.js 8.10 имеют эту функцию.

Я только что проверил это в своем браузере и в Node.js (v8.11) и могу подтвердить, что:

node -e "console.log('nothing@xyz, bla'.match(/(?<=@[A-Za-z]+,)\s+/))"

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

const hit = 'nothing@xyz, bla'.match(/(@[A-Za-z]+,)\s+/)
hit[0].replace(hit[1])

Если больше ничего не работает, взгляните на этот проект, который пытается реализовать Lookbehind (я не проверял его): http://blog.stevenlevithan.com/archives/javascript-regex-lookbehind

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

Я обновил свой ответ на новом входе

console.clear();

var inputEl = document.querySelector('#input')
var outputEl = document.querySelector('#output')

function rep (e) {
  var input = e.target.value;
  var reg = /@([a-z]+?\s*?)+,(\s+[a-z]+)+(\s\[[a-z]+\])?/gim



  matches = input.match(reg);
  var output = input;

  if (matches) {
    replaceMap = new Map()
    for (var i = 0; i < matches.length; i++) {
      var m = matches[i]
        .replace(/\[/, '\\[')
        .replace(/\]/, '\\]')
      replaceMap.set(m, matches[i].replace(/\s+/gm, ''))
    }
    for (var [s,r] of replaceMap) {
      output = output.replace(new RegExp(s, 'gm'), r) 
    }
  }

  outputEl.textContent = output
}

inputEl.addEventListener('input', rep)
inputEl.dispatchEvent(new Event('input'))
textarea {
  width: 100%; 
  min-height: 100px;
}
<h3>Input</h3>
<textarea id="input">@Lopez de la Cerda, Antonio Gabriel Hugo David [Author]. I'm the father of @Marquez, Maria</textarea>
<h3>Output (initially empty)</h3>
<p id="output"></p>
<h3>Expected result (on initial input)</h3>
<p>@LopezdelaCerda,AntonioGabrielHugoDavid[Author]. I'm the father of @Marquez,Maria</p>

Резервное копирование старого ответа (по историческим причинам)

Это работает по крайней мере в Chrome с этим регулярным выражением:

/(?<=@[a-z]+,)\s+(?![a-z]+\s+\[[a-z]+\])|(?<=(@[a-z]+,\s[a-z]+))\s+(?=\[[a-z]+\])/gmi

См .: https://regex101.com/r/elTkRe/4

Но вы не можете использовать его в PCRE, потому что не разрешено иметь квантификаторы в вид сзади. Они должны быть фиксированной ширины. Смотрите ошибки справа здесь: https://regex101.com/r/ZC3XmX/2

Решение без оглядки и взгляда в будущее

console.clear();

var reg = /(@[A-Za-z]+,\s[A-Za-z]+)(\s+)(\[[A-Za-z]+\])|(@[A-Z|a-z]+,)(\s+)/gm

var probes = [
  '@gotAMatch,     <<<',
  '@LongerWithMatch,        <<<',
  '@MatchHereAsWell,    <<<',
  '@Yup,         <<<<',
  '@noMatchInThisLine,<<<<<',
  '@match, match    [match]<<<<<<<',
  '@    noMatchInThisLine,    <<<<'
]

for (var i in probes) {
  console.log(probes[i].replace(reg, '$1$3$4'))
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...