Мы можем определить следующее регулярное выражение.
R = /
# split after an open paren if not followed by a digit
(?<=\() # match is preceded by an open paren, pos lookbehind
(?!\d) # match is not followed by a digit, neg lookahead
[ ]* # match >= 0 spaces
| # or
# split before an open paren if paren not followed by a digit
(?= # begin pos lookahead
\( # match a left paren...
(?!\d) # ...not followed by a digit, neg lookahead
) # end pos lookahead
[ ]* # match >= 0 spaces
| # or
# split before a closed paren if paren not preceded by a digit
(?<!\d) # do not follow a digit, neg lookbehind
(?=\)) # match a closed paren, pos lookahead
[ ]* # match >= 0 spaces
| # or
# split after a closed paren
(?<=\)) # match a preceding closed paren, pos lookbehind
[ ]* # match >= 0 spaces
| # or
# match spaces not preceded by *, = or + and followed by a letter
(?<![*=+\/-]) # match is not preceded by one of '*=+\/-', neg lookbehind
[ ]+ # match one or more spaces
| # or
# match spaces followed by a letter
[ ]+ # match one or more spaces
(?=\() # match a left paren, pos lookahead
/x # free-spacing regex definition mode
В первом примере мы имеем следующее.
algo1 = 'ABC * DEF * GHI Round(3) = JKL * MNO * PQR Round(0) = SAVE'
expected1 = ['ABC', '* DEF', '* GHI', 'Round(3)', '= JKL', '* MNO',
'* PQR', 'Round(0)', '= SAVE']
algo1.split(R) == expected1
#=> true
Во втором примере мы имеем следующее.
algo2 = '(ABC + DEF + (GHI * JKL)) - ((MNO + PQR + (STU * VWX)) * YZ) Round(0) + SUM(AAA) = SAVE'
expected2 = ['(', 'ABC', '+ DEF', '+', '(', 'GHI', '* JKL', ')', ')', '-',
'(', '(', 'MNO', '+ PQR', '+', '(', 'STU', '* VWX', ')', ')',
'* YZ', ')', 'Round(0)', '+ SUM', '(', 'AAA', ')', '= SAVE']
algo2.split(R) == expected2
#=> true
Регулярное выражение обычно записывается следующим образом:
R = /(?<=\()(?!\d) *|(?=\((?!\d)) *|(?<!\d)(?=\)) *|(?<=\)) *|(?<![*=+\/-]) +| +(?=\()/
В режиме свободного пробела я заключил пробелы в класс символов ([ ]
);иначе они будут удалены перед оценкой выражения.В этом нет необходимости, если регулярное выражение написано условно.