Как сказал paxdiablo, вы почти наверняка не хотите использовать здесь регулярное выражение. Предложение split
неплохое; Я сам, вероятно, использовал бы здесь парсер & mdash; есть много структур для использования. Идея заключается в том, что вы формально определяете синтаксис того, что у вас есть - что-то вроде того, что вы нам дали, только строго. Так, например: field
- это последовательность символов, не заключенных в одинарные кавычки, заключенные в одинарные кавычки; fields
- любое число field
с, разделенных пробелом, a |
и больше пробелов; tilde
- символы без скобок, окруженные (~
и )
; expr
- это fields
, необязательный пробел, необязательный tilde
, =
, необязательный пробел и еще один fields
. То, как вы это выражаете, зависит от языка, который вы используете. Например, в Haskell, используя библиотеку Parsec, вы пишете каждый из этих анализаторов следующим образом:
import Text.ParserCombinators.Parsec
field :: Parser String
field = between (char '\'') (char '\'') $ many (noneOf "'\n")
tilde :: Parser String
tilde = between (string "(~") (char ')') $ many (noneOf ")\n")
fields :: Parser [String]
fields = field `sepBy` (try $ spaces >> char '|' >> spaces)
expr :: Parser ([String],Maybe String,[String])
expr = do left <- fields
spaces
opt <- optionMaybe tilde
spaces >> char '=' >> spaces
right <- fields
(char '\n' >> return ()) <|> eof
return (left, opt, right)
Точное понимание того, как работает этот код, не очень важно; основная идея состоит в том, чтобы разбить то, что вы анализируете, выразить это в формальных правилах и создать его обратно из меньших компонентов. И для чего-то подобного это будет намного чище, чем регулярное выражение.
Если вы действительно хотите получить регулярное выражение, вот, пожалуйста (едва протестировано):
^\s*('[^']*'((\s*\|\s*)'[^'\n]*')*)?(\(~[^)\n]*\))?\s*=\s*('[^']*'((\s*\|\s*)'[^'\n]*')*)?\s*$
Видишь, почему я рекомендую парсер? Когда я впервые написал это, я понял по минимум две вещи, которые я подобрал (по одной на тест), и, вероятно, есть что-то еще. И я не вставлял группы захвата, где вы хотели их, потому что я не знал, куда они пойдут. Теперь да, я мог бы сделать это более читабельным, вставив комментарии и т. Д. И в конце концов, regexen имеет свое применение! Однако дело в том, что это не один из них. Палка с чем-то лучше.