2017-01-21 3 views
2

кто-нибудь помочь мне написать RegEx для следующих случаевRegEx для извлечения скобку и имя функции

  • SomeString() =>['somestring']
  • SomeString() [10] =>['somestring','',10]
  • SomeString (» argString ') =>['somestring', 'argString']
  • SomeString (' argString ') [10] =>['somestring', 'argString',10]
  • SomeString ({prop1:' v1' , prop2: 'v2'}) =>['somestring', {prop1:'v1',prop2:'v2'}]

  • SomeString ({prop1: 'v1', prop2: 'v2'}) [100] =>['somestring', {prop1:'v1',prop2:'v2'},100]

Это я пытался до сих пор

var regExp = /\b[^()]+\((.*)\)+\[(.*?)]/; 
var matches = regExp.exec('somestring()[10]'); 
+0

Почему вы используете regexp для декодирования того, что похоже на JS? Что вы планируете делать с результатами? Вам нужно обработать что-то вроде 'somestring (foo (bar))' или 'somestring (foo [10] (bar))' или 'somestring (foo (bar) [10])' или 'somestring ({ prop1: foo (bar) [10]}) '? –

+0

@torazaburo внутри paranthesis все может быть там, моя единственная забота - просто получить содержимое внутри paranthesis – Shafeeque

+0

В этом случае это будет очень сложно сделать с regexp, так как regexp не справляется с вложенным синтаксисом. Можете ли вы добавить такой пример к нашему вопросу, чтобы другие люди, отвечающие, имели тестовые примеры для работы? Маленький парсер может работать лучше для вас. –

ответ

2

Это может сработать:

var input = ['somestring()', 'somestring()[10]', "somestring('argString')", "somestring('argString')[10]", "somestring({prop1:'v1',prop2:'v2'})", "somestring({prop1:'v1',prop2:'v2'})[100]"]; 

console.log(input.map(function(v) { 
    let result = v.match(/(.*)\((.*)\)(\[([^\]]*)\])?/); 

    return [result[1], result[2], result[4]]; 
})); 
1

Вы просто необходимо исключить закрывающие скобки:

var regExp = /\b[^()]+\(([^)]*)\)(\[[^\]]*\])?/; 

Это сломается, если у вас есть строка, как показано ниже:

somestring({myKey: myFunc()})[myArray[0]] 
+0

ваше регулярное выражение не работает во всех случаях – smnbbrv

2

Вы можете свести на нет (, ), [, ] из спичек

let re = /[^()\[\]]+/g; 

let res = "somestring({prop1:'v1',prop2:'v2'})[100]".match(re); 
+0

Спасибо, возможно ли добавить пустое значение, если в функции paranthesis нет аргумента? – Shafeeque

0

Я попытался бы справиться с этим с Proxy, следующим образом:

const somestring = new Proxy(() => {}, { 
    apply(target, thisArg, [arg = '']) { 
    return new Proxy(['somestring', arg], { 
     get(target, prop) { 
     if (!isNaN(String(prop))) return [...target, prop]; 
     return target[prop]; 
     } 
    }); 
    } 
}); 

console.log(
    somestring(), 
    somestring()[10], 
    somestring('argString'), 
    somestring('argString')[10], 
    somestring({prop1:'v1',prop2:'v2'}), 
    somestring({prop1:'v1',prop2:'v2'})[100] 
); 

Это нормально работает в узле, но не в консоли Chrome devtools, потому что последний, по-видимому, пытается вызвать get для каждого элемента при сериализации на консоли с использованием console.log.

выход

Node:

[ 'somestring', '' ] 
[ 'somestring', '', '10' ] 
[ 'somestring', 'argString' ] 
[ 'somestring', 'argString', '10' ] 
[ 'somestring', { prop1: 'v1', prop2: 'v2' } ] 
[ 'somestring', { prop1: 'v1', prop2: 'v2' }, '100' ] 

Основная идея здесь заключается в создании функции прокси-сервера, который при вызове (apply) возвращает ['somestring', arg] массив, но и обернуть прокси вокруг того, что ловушки доступы собственности (get) например [10], и в этом случае вернуть ['somestring', arg, 10].

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