RegEx все совпадения между - PullRequest
       3

RegEx все совпадения между

0 голосов
/ 22 января 2020

Я бы хотел сопоставить все foo и bar (те, которые имеют длину от 8 символов) в этом тексте foo bar foo 8 bar foo bar 8 foo bar foo.

Это то, что я пробовал: 8.*(foo|bar).*8

Проблема в том, что он соответствует только последнему bar как (я верю) жадному квантификатору go, насколько он может.

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

Мой текущий RegEx, чтобы вы могли лучше понять, что я имею в виду: https://regex101.com/r/p0tQws/1

Ответы [ 4 ]

0 голосов
/ 22 января 2020

(При попытке в регулярном выражении 101 кажется, что он разрешает просмотр без фиксированной ширины в Javascript. Если это работает для вас, вы можете попробовать это)

Если ваша среда позволяет с фиксированной шириной, вы можете попробовать

(?<=8.*)(foo|bar)(?=.*8)
Explanation:
(?<=   )                   positive look-behind, i.e. preceded by
    8.*                        8, then zero-or-more character
        (foo|bar)          "foo" or "bar", in capture group
                 (?=   )   postiive look-ahead, i.e. followed by
                    .*8        zero-or-more characters, then 8

https://regex101.com/r/p0tQws/3

0 голосов
/ 22 января 2020

Альтернативой захвату регулярных выражений будет split и map или аналогичная функция массива:

let   str = 'foo bar foo 8 bar foo cruft foo fnooz bar 8 foo bar foo'
let   is8 = false

// split string on spaces 
str.split(/\s/).map(el => {
  // toggle 'is8' when encountered
  if(el == 8)
    is8 = !is8

  // 'is8' is true, and el matches regex
  if(is8 && /(foo|bar)/.test(el)) 
  {        
    // do something with el between the 8's e.g. uppercase
    return el.toUpperCase()
  }
  return el
}).join(' ')

// yields "foo bar foo 8 BAR FOO cruft FOO fnooz BAR 8 foo bar foo"
0 голосов
/ 22 января 2020

Вы можете сопоставить первое 8, затем захватить в группе 1 то, что находится между вторым появлением 8, и использовать положительный прогноз, если вы также хотите получить совпадение, если есть другое вхождение после 8.

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

 \b8\s+([^8]+)(?=\s+8\b)
  • \b8 Совпадение 8, которому предшествует слово bounary
  • \s+ Совпадение 0+ пробельных символов
  • ([^8]+) Захват группы 1, сопоставление с любым символом, кроме 8 1+ раз
  • (?= Позитивный взгляд
    • \s+8\b Совпадение 0+ пробельных символов и совпадение 8, за которым следует граница слова
  • ) Закрыть взгляд

Regex demo

const pattern = /\b8\s+([^8]+)(?=\s+8\b)/;
let str = "foo bar foo 8 bar foo bar 8 foo bar foo";
str = str.match(pattern)[1].split(" ");
console.log(str);

Если вы также хотите иметь возможность сопоставлять, например, 800 между, вы можете использовать

\b8\s+(.+?)(?=\s+8\b)

Regex demo

0 голосов
/ 22 января 2020

8([^8]*(foo|bar)+[^8]*)8

См. regex101 для объяснения

По сути, это была проблема:

Повторная группа захвата будет захватить только последнюю итерацию Поместите группу захвата вокруг повторяющейся группы, чтобы захватить все итерации, или вместо этого используйте группу без захвата, если вас не интересуют данные

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