2015-09-14 3 views
0

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

Сценарий:

var str = "hello 1 test test hello 2"; 
var patt = /(hello \S+)/g; 
var res = str.split(patt); 
//var res = str.search(patt); 
if(res!=null) { 
    for(var i=0;i<res.length;i++) console.log(i+res[i]); 
} 

Выход:

0 
1hello 1 
2 test test 
3hello 2 
4 

Ожидаемый результат:

0hello 1 
1hello 2 

Что я делать неправильно ?!

ответ

1

Похоже, что вы ищете спички, а не разделяя строку

Использование str.match(patt)

str.match

Вместо этого, ваш ответ разделив эту строку дважды, так как регулярное выражение совпадает в двух местах , Разделение строки по регулярному выражению дает 3 части. Перед матчем, матчем и после матча.

Ваша строка соответствует дважды. Это означает, что этот процесс произошел дважды, в результате получилось 5 частей, результат был показан (две части пустые).

+1

Это! Спасибо друг! Я помечаю ответ как завершенный после 8 минут более – marius

+0

Спасибо. Если вы используете регулярное выражение много, инструмент, который я часто использую, и найти очень полезным, это [Regexr] (http://www.regexr.com) – MetalMichael

0

Match подход

С match, это гораздо проще, просто использовать /hello\s+\S+/g:

var str = "hello 1 test test hello 2"; 
 
var patt = /hello\s+\S+/g; 
 
var res = str.match(patt); 
 
if(res!=null) { 
 
    for(var i=0;i<res.length;i++) 
 
     console.log(i+res[i]); 
 
     }

Обратите внимание, что вам не нужны какие-либо захватив группы в этом случае, как вы не используя захваченный текст, вам нужен весь согласованный текст. Кроме того, \s+ будет соответствовать любому пробелу между hello и последовательностью символов без пробелов.

Split подход

Вы должны соответствовать остальной части строки, которая после hello \S+ и удалить пустые записи перед выводом их:

var str = "hello 1 test test hello 2"; 
 
var patt = /(hello \S+).*?(?=$|hello \S)/g; 
 
var res = str.split(patt); 
 
//var res = str.search(patt); 
 
if(res!=null) { 
 
    res = res.filter(Boolean); 
 
    for(var i=0;i<res.length;i++) 
 
     if (res[i]) { 
 
     console.log(i+res[i]); 
 
     } 
 
}

Результат:

0hello 1 
js:21 1hello 2 

Регулярное выражение - (hello \S+).*?(?=$|hello \S) - сопоставляет и фиксирует hello + последовательность символов без пробелов, а затем любые символы, кроме строки новой строки, до конца строки или следующего hello + символы без пробелов.

Я использовал res.filter(Boolean); для удаления пустых элементов в результирующем массиве (который почти всегда присутствует при расщеплении с регулярным выражением).

+0

, что черная магия это? почему он так отличается от обычного reg ex? https://regex101.com/r/iP8lV6/18 – marius

+0

Не могли бы вы пояснить, что такое «черная магия», которую вы видите здесь? У меня нормальное регулярное выражение. Я просто предположил, что вы хотите использовать «split» здесь. С 'match', это намного проще, конечно. –

+0

Я добавил подход 'match' с удаленной группой захвата из регулярного выражения. –

0

Вы использовали split, тогда у вас есть массив со всеми значениями до и после каждого матча /(hello \S+)/g.

Вы хотите использовать match:

"hello 1 test test hello 2".match(/(hello \S+)/g); 
// ["hello 1", "hello 2"] 
0

split ... разбивает строку.

Так же, как расщепление x,y,z от /(,)/ даст вам ["x", ",", "y", ",", "z"], вы получите результат, увиденный здесь.

То, что вы хотели сделать, итерация за матчей:

str.match(/(hello \S+)/g)