2015-01-13 1 views
0

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

- (NSString *)functionPattern 
{ 
    return @"[A-Za-z]{1,}\\([A-Za-z0-9,\\(\\)]{1,}\\)"; 
} 

- (void)test 
{ 
    NSString *formula = @"AVERAGE(G17,G18,AVERAGE(G20,G21,MIN(G30,G31)))"; 

    NSError *error; 
    NSRegularExpression *functionRegex = [NSRegularExpression regularExpressionWithPattern:[self functionPattern] 
                        options:NSRegularExpressionCaseInsensitive 
                        error:&error]; 
    if (error) { 
     NSLog(@"error"); 
     return; 
    } 

    NSArray *matches = [functionRegex matchesInString:formula options:0 range:NSMakeRange(0, formula.length)]; 
    for (NSUInteger i = 0; i < matches.count; i++) { 
     NSTextCheckingResult *result = matches[i]; 
     NSString *match = [formula substringWithRange:result.range]; 
     NSLog(@"%@", match); 
    } 
} 

Мое естественное Ожидалось, чтобы получить 3 матча: СРЕДНИЕ (.. .), AERAGE (...) и MIN (...). Удивительно для меня, я получаю только один матч: AVERAGE(G17,G18,AVERAGE(G20,G21,MIN(G30,G31))).

Если формула AVERAGE(G17,G18)+AVERAGE(G20,G21,MIN(G30,G31)), я получу 2 совпадения: AVERAGE(G17,G18) и AVERAGE(G20,G21,MIN(G30,G31)). Другими словами, после нахождения совпадения поиск шаблона не выполняется в диапазоне совпадающей строки.

Прошу совета, как преодолеть это и найти все возможные соответствия. Я что-то пропустил здесь?

Что я делаю, это синтаксический анализ и оценка математических выражений. Все работает нормально, за исключением случаев вложенных функций. Если я знаю все возможные имена функций заранее, может ли это быть каким-то образом использовано?

Я надеюсь на более или менее элегантный подход; если я могу избежать таких вещей, как «отключение имени функции и круглых скобок»

Помощь очень ценится.

+0

Я не знаю, если вы можете сделать регулярное выражение, которое делает то, что вы хотите, но вы можете * * сдирать имя функции и круглые скобки, а затем запустить регулярное выражение снова на остальной текст. – user3386109

+0

@ user3386109 спасибо за мысль, я тоже это рассмотрел. Хотелось бы, чтобы я мог избежать этого. Я немного отредактировал вопрос, пожалуйста, проверьте. – user1244109

ответ

1

Вы не можете делать то, что хотите, по крайней мере так, как хотите.

Регулярные выражения являются технически грамматикой типа 3 и не могут описывать рекурсивные языки; ваши математические выражения могут содержать другие математические выражения.

может сделать что-то по линии того, что вы говорите, что не хотите делать. Например, вы можете сопоставить выражение, содержащее только одну пару сбалансированных круглых скобок, поэтому в AVERAGE(G20,G21,MIN(G30,G31)) вы можете найти MIN(G30,G31). Если вы заменили матч маркером и снова совпали, вы можете соответствовать следующему уровню и т. Д. Но это не - хороший способ сделать это.

Общие математические выражения могут быть описаны грамматикой типа 2 и могут быть легко проанализированы с использованием рекурсивного анализатора спуска. Такие парсеры очень легко писать. По сути, вы записываете грамматику, которую хотите разбор, а затем записываете функцию для каждого произведения. Google поможет вам начать этот маршрут.

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

НТН

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

  • Нет связанных вопросов^_^