2013-11-08 4 views
2

Я использую это выражение:регулярного выражения в JavaScript соответствует слишком много

"g{field1}={field2}a".match(/{([^\{\}]+)\}/g) 

Что мне нужно, чтобы получить «field1» и «поле2», но он возвращает массив с «{field1}» и "{field2}".

+0

Поскольку регулярные выражения JS не имеют lookbehinds, просто удалите первый и последний символ строк – Doorknob

+0

Что вы имеете в виду, Doorknob? –

+1

Проверка наличия символа перед определенным совпадением без соответствия символу не поддерживается в регулярных выражениях JS. ([подробнее] (http://www.regular-expressions.info/lookaround.html)) Вместо этого просто возьмите каждую строку и удалите первый и последний символы. – Doorknob

ответ

3

Вы можете использовать exec, которые могут возвращать несколько групп, захватив на матчи.

var re = /{([^\{\}]+)\}/g, 
    matches = [], 
    input = "g{field1}={field2}a", 
    match; 

while (match = re.exec(input)) matches.push(match[1]); 

console.log(matches); 

Вы также можете повторно написать регулярное выражение (здесь это зависит от того, что строка ввода может быть):

var matches = "g{field1}={field2}a".match(/{([^}]+)}={([^}]+)}/).slice(1); 

console.log(matches); 
+0

Не знал, что я могу использовать совпадение несколько раз в одной строке. Это просто очень элегантно. –

+1

@ArnaudWeil 'exec' заставит регулярное выражение отслеживать индекс последнего совпадения, так как это свойство' lastIndex'. Однако убедитесь, что вы используете «exec», как показано с помощью * глобального * флага, или у вас будет бесконечный цикл;) – plalx

+0

Downvote, действительно? Было бы неплохо узнать, почему я могу исправить любое неверное утверждение. – plalx

2

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

"g{field1}={field2}a".match(/{([^\{\}]+)\}/g).map(function(i){return i.slice(1,-1)}) 
+0

Это то, что подразумевал Doorknob, и это решение. Я disapointed JS regexps не делают этого, но это решение в любом случае. –

0
"g{field1}={field2}a".match(/([^g=a\{\}]+)/g) 

возвращает

["field1", "field2"] 
+2

Err ... кроме того, что он не будет работать ни на какой другой вход !!! Я мог бы также использовать ["field1", "field2"] hardcoded в этом случае ... –

+0

Правда, слишком быстро с этим ответом :-( –

1

Вы можете использовать предпросмотр

"g{field1}={field2}a".match(/[^\{\}]+(?=\})/g)

это будет соответствовать любому символу, который не { или }, если согласованный набор символов сопровождается }

0

Вы также можете сделать:

'g{field1}={field2}a'.split(/[{}]/).filter(function(a,i){return i%2;}); 

при условии, что строка всегда содержит соответствие «{ } ". Существует также:

'g{field1}={field2}a'.split(/^[^{]*\{|\}[^{]*\{|\}[^{]*$/g).slice(1,-1); 

, оба из которых будут работать на любом количестве {...} пар (от 0 до n).

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