RegEx для разделения списка слов с несколькими группами захвата - PullRequest
3 голосов
/ 20 мая 2019

У меня есть следующая строка:

one two three four five six seven eight nine

И я пытаюсь построить регулярное выражение, которое группирует строку в три группировки:

  1. Группа 1: «один два три»
  2. Группа 2: «четыре пять шесть»
  3. Группа 3: «семь восемь девять»

Я пробовал варианты (.*\b(one|two|three)?)(.*\b(four|five|six)?)(.*\b(seven|eight|nine)?), но этот шаблон разбивает полное совпадение на одну группу, содержащую полную строку - демо можно найти здесь .

Попытка (.*\b(one|two|three))(.*\b(four|five|six))(.*\b(seven|eight|nine)), кажется, приближает меня к тому, что я хочу, но панель информации о совпадении показывает, что шаблон идентифицирует два совпадения, каждое из которых содержит шесть групп захвата.

Я использую оператор OR, потому что группы могут быть любой длины, например, two three four, применение шаблона к этой строке должно идентифицировать две группы -

  1. Группа 1: «два»
  2. Группа 2: «три четверки».

Ответы [ 3 ]

2 голосов
/ 20 мая 2019

Большое регулярное выражение, которое, вероятно, делает это

(?=.*\b(?:one|two|three|four|five|six|seven|eight|nine)\b)(\b(?:one|two|three)(?:\s+(?:one|two|three))*\b)?.+?(\b(?:four|five|six)(?:\s+(?:four|five|six))*\b)?.+?(\b(?:seven|eight|nine)(?:\s+(?:seven|eight|nine))*\b)?

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

Читаемая версия

 (?=
      .* \b 
      (?:
           one
        |  two
        |  three
        |  four
        |  five
        |  six
        |  seven
        |  eight
        |  nine
      )
      \b 
 )
 (                             # (1 start)
      \b   
      (?: one | two | three )

      (?:
           \s+ 
           (?: one | two | three )
      )*
      \b 
 )?                            # (1 end)

 .+? 
 (                             # (2 start)
      \b        
      (?: four | five | six )

      (?:
           \s+ 
           (?: four | five | six )
      )*
      \b     
 )?                            # (2 end)

 .+?   
 (                             # (3 start)
      \b          
      (?: seven | eight | nine )

      (?:
           \s+ 
           (?: seven | eight | nine )
      )*
      \b   
 )?                            # (3 end)
1 голос
/ 20 мая 2019

В этом ответе предполагается, что вы хотите найти группы из трех числовых слов одновременно:

x <- c("one two three four five six seven eight nine")
regexp <- gregexpr("\\S+(?:\\s+\\S+){2}", x)
regmatches(x, regexp)[[1]]

[1] "one two three"    "four five six"    "seven eight nine"

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

parts <- strsplit(x, " ")[[1]]
output <- character(0)
for (i in seq(from=1, to=length(parts), by=3)) {
    output <- c(output, paste(parts[i], parts[i+1], parts[i+2]))
}
output

[1] "one two three"    "four five six"    "seven eight nine"
0 голосов
/ 20 мая 2019

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

((one|two|three)\s.*?)((four|five|six)\s.*?)((seven|eight|nine)\s.*)

enter image description here

RegEx

Если это выражение нежелательно, вы можете изменить / изменить выражения в regex101.com .

RegEx Circuit

Вы также можете визуализировать свои выражения в jex.im :

enter image description here

JavaScript Demo

Этот фрагмент показывает, что могут возвращать различные группы захвата:

const regex = /((one|two|three)\s.*?)((four|five|six)\s.*?)((seven|eight|nine)\s.*)/gm;
const str = `one two three four five six seven eight nine

two three four six seven eight`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...