2015-11-10 3 views
0

Im новой для регулярных выражений в JavaScript и у меня возникают проблемы при получении массива спичек из текстовой строки, как показано ниже:JavaScript регулярные выражения и захвата группы

Sentence would go here 
-foo 
-bar 
Another sentence would go here 
-baz 
-bat 

Я хотел бы получить массив совпадений, как это:

match[0] = [ 
    'foo', 
    'bar' 
] 
match[1] = [ 
    'baz', 
    'bat' 
] 

Итак, подведем итог, я ищу это:

"любое тире + слово (-foo, -бар, и т.д.), который приходит ПОСЛЕ предложение «

Может ли кто-нибудь предоставить формулу, которая будет захватывать все итерации вместо последнего, поскольку группа повторного захвата будет, по-видимому, только захватывать последнюю итерацию. Простите меня, если это глупый вопрос. Я использую regex101, если кто-то хочет отправить мне несколько тестов.

+0

Это может быть проще просто перебрать все строки и собирать данные по желанию. –

+0

Являются ли дефисы всегда в начале линии? –

ответ

1

Просто матч две строки, начинающиеся с - и предшествует символ новой строки, если этого достаточно.

\n-(.*)\r?\n-(.*) 

См. regex demo at regex101. Для получения совпадений используйте exec() method.

var re = /\n-(.*)\r?\n-(.*)/g; var m; 
 

 
var str = 'Sentence would go here\n-foo\n-bar\nAnother sentence would go here\n-baz\n-bat'; 
 

 
while ((m = re.exec(str)) !== null) { 
 
    if (m.index === re.lastIndex) re.lastIndex++; 
 
    document.write(m[1] + ',' + m[2] + '<br>'); 
 
}

+0

Спасибо. Я закончил с этим с вашей помощью: (^ \ "[\ s \ S] *? \") \ N - (. *) \ R? \ N - (. *) – Coldstar

+0

Единственное, что «соответствует двум строкам «где мне нужно будет« соответствовать N строкам ». Я пойму это, однако, еще раз спасибо – Coldstar

+1

@bobblebubble. Вам не нужно увеличивать значение 'lastIndex', потому что с помощью флага' g' автоматически это сделает для вас. – tkellehe

1

Захваты Regexp не очень хорошо работают с неограниченным количеством групп. Скорее всего, расщепление работает лучше здесь:

var text = document.getElementById('text').textContent; 
 
var blocks = text.split(/^(?!-)/m); 
 
var result = blocks.map(function(block) { 
 
    return block.split(/^-/m).slice(1).map(function(line) { 
 
     return line.trim(); 
 
    }); 
 
}); 
 
document.getElementById('text').textContent = JSON.stringify(result);
<div id="text">Sentence would go here 
 
-foo 
 
-bar 
 
Another sentence would go here 
 
-baz 
 
-bat 
 
</div>

2

Первое регулярное выражение я придумал следующий:

/([^-]+)(-\w*)/g 

Первая группа ([^-]+) захватывает все, что не прочерк. Затем мы следуем за этой фактической группой захвата, которую хотим (-\w+). Мы добавляем флаг g, чтобы объект регулярного выражения отслеживал последнее место, на которое он смотрел. Это означает, что каждый раз, когда мы запускаем regex.exec(search), мы получаем следующий матч, который вы видите в regex101.

Примечание: \w для JavaScript эквивалентен [a-zA-Z0-9_]. Итак, если вы хотите просто буквы использовать это вместо \w: [a-zA-Z]


Вот код, который реализует это регулярное выражение.

<p id = "input"> 
    Sentence would go here 
    -foo 
    -bar 
    Another sentence would go here 
    -baz 
    -bat 
</p> 

<p id = "output"> 

</p> 

<script> 
    // Needed in order to make sure did not get a sentence. 
    function check_for_word(search) {return search.split(/\w/).length > 1} 
    function capture(regex, search) { 
     var 
     // The initial match. 
      match = regex.exec(search), 
     // Stores all of the results from the search. 
      result = [], 
     // Used to gather results. 
      gather; 
     while(match) { 
      // Create something empty. 
      gather = []; 
      // Push onto the gather. 
      gather.push(match[2]); 
      // Get the next match. 
      match = regex.exec(search); 
      // While we have more dashes... 
      while(match && !check_for_word(match[1])) { 
       // Push result on! 
       gather.push(match[2]); 
       // Get the next match to be checked. 
       match = regex.exec(search); 
      }; 
      // Push what was gathered onto the result. 
      result.push(gather); 
     } 
     // Hand back the result. 
     return result; 
    }; 
    var output = capture(/([^-]+)(-\w+)/g, document.getElementById("input").innerHTML); 
    document.getElementById("output").innerHTML = JSON.stringify(output); 
</script> 

Использование немного измененную регулярное выражение, вы можете получить больше того, что вы ищете.

/[^-]+((?:-\w+[^-\w]*)+)/g 

Дополнительный бит [^-\w]* позволяет там быть какая-то разделение между каждой черточки слова. Затем была добавлена ​​не захватывающая группа (?:), чтобы дать + одну или несколько штрихов. Нам также не нужен () около [^-]+, потому что данные больше не нужны, как вы увидите ниже. Первый из них более гибкий, чем то, что может сломаться между чертовыми словами, но я считаю, что это намного чище.

function capture(regex, search) { 
 
    var 
 
\t // The initial match. 
 
\t  match = regex.exec(search), 
 
\t // Stores all of the results from the search. 
 
\t  result = [], 
 
\t // Used to gather results. 
 
\t \t gather; 
 
\t while(match) { 
 
\t  // Create something empty. 
 
\t  gather = []; 
 
\t \t 
 
\t  // Break up the large match. 
 
\t  var temp = match[1].split('-'); 
 
\t \t for(var i in temp) 
 
\t \t { 
 
\t \t  temp[i] = temp[i].split(/\W*/).join(""); 
 
\t \t \t // Makes sure there was actually something to gather. 
 
\t \t  if(temp[i].length > 0) 
 
\t \t   gather.push("-" + temp[i]); 
 
\t \t } 
 
\t \t 
 
\t \t // Push what was gathered onto the result. 
 
\t \t result.push(gather); 
 
\t \t 
 
\t \t // Get the next match. 
 
\t \t match = regex.exec(search); \t 
 
\t }; 
 
\t // Hand back the result. 
 
\t return result; 
 
}; 
 
var output = capture(/[^-]+((?:-\w+[^-\w]*)+)/g, document.getElementById("input").innerHTML); 
 
document.getElementById("output").innerHTML = JSON.stringify(output);
<p id = "input"> 
 
Sentence would go here 
 
-foo 
 
-bar 
 
Another sentence would go here 
 
-baz 
 
-bat 
 
My very own sentence! 
 
-get 
 
-all 
 
-of 
 
    -these! 
 
</p> 
 

 
<p id = "output"> 
 

 
</p>

Смежные вопросы