2015-06-30 4 views
1

Я хочу преобразовать строку выражения в массивы. Для строки (10+2)/33 ожидаемым результатом является ['(', '10', '+', '2', ')', '/', '33']. Там могут быть пробелы между ними, а действительными операторами являются +-*/().Как разбить выражение на массив?

ответ

1

Вы можете использовать этот шаблон:

"(10+2)/33".split(/\b|(?!\d)/) 

(Очевидно, что цель здесь, чтобы разделить строку, а не проверять, если символы разрешены).

Идея заключается в том, чтобы использовать тот факт, что (, ), +, -, /, * одиночные символы, которые не являются в классе \w характера. Таким образом, \b будет соответствовать, когда за цифрой следует один из этих символов и наоборот. (?!\d)(отрицательный lookakead: не следует цифрой), так как это вторая альтернатива, похожа на \B(?!\d) и будет соответствовать двум признакам.

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

"(10+2)/33".split(/\s*\b\s*|\s*(?!\d)/) 

Обратите внимание, что он может генерировать пустой элемент в начале.

Чтобы избежать этой проблемы, вы можете использовать метод scan с различным рисунком:

" (2 (10+2)/33) ".scan(/\G\s*\K(?:\d+|\S)/) 

Где \G гарантирует, что все матчи являются смежными с начала строки и \K отбрасывает все налево от матча результат (возможные белые пробелы).

+0

Я могу сделать result_array.compact для удаления пробелов. Спасибо! – BugsBunny

0
"(10 + 2)/33".delete(" ").split(/(\D)/).reject(&:empty?) 
# => ["(", "10", "+", "2", ")", "/", "33"] 
0

Вы также можете использовать функцию scan.

> s = "(10+2)/33" 
> s.scan(/\d+|[^\s\w]/) 
=> ["(", "10", "+", "2", ")", "/", "33"] 
> s.scan(/\d+|[^\s\d]/) 
=> ["(", "10", "+", "2", ")", "/", "33"] 
Смежные вопросы