Однако в этом случае у пользователя есть возможность ввести «x 1», и это будет воспринято как одна лексема «x1»:variable. Можно ли учесть все условия в одном регекспе, чтобы не производить предварительное удаление пробельных символов?
Предварительно удаляя пробелы вы не упрощаете задачу разбора выражения, а напротив — усложняете.
Уберите удаление пробелов и добавьте вместо этого пробелы в качестве ещё одной альтернативы в
regexp идущий сейчас вторым.
Т.е.:
var match = Regex.Match(infix, @"[-+*/^%()]|[A-Za-z][A-Za-z0-9]*|[+-]?[0-9]+\.?[0-9]*|[ \t]+");
Таким образом слипания токенов происходить не будет, а приходящие среди значащих токенов пробелы
можно игнорировать в последующей обработке.
При более-менее серьёзной задаче, естественно, стоит написать нормальный лексер, а не городить огород из Regex. И модифицировать его проще будет и работать он будет быстрее.
Как лучше всего проверить валидность выражения?
…
можно ли обойтисть только регулярками, или лучше заюзать генератор вроде Сосо/R
Задачу проверки корректности арифметического выражения средствами одних толкьо regexp-ов, насколько мне известно, решить нельзя.
Можно задействовать генератор парсеров, а можно написать простенький свой, работающий по
методу рекурсивного спуска.
Всё зависит от того, что вам нужно — разобрать выражение или разобраться, как разбирать выражения.
Если вас интересует тема парсеров/компиляторов и т.п., то однозначно стоит прочитать «
Компиляторы. Принципы, технологии и инструментарий».
Построение парсера арифметических выражений есть там в качестве пошагового примера.