Я не использую C #, но я предполагаю, что он использует pcre ... если так,
"([^#]*)#.*"
с призывом к «совпадению». Вызов 'search' не нуждается в конце ". *"
Парены определяют «группу поддержки»; [^ #] означает любой символ, который не является '#'
Вы, наверное, пробовали что-то вроде
"(.*)#.*"
и обнаружил, что он терпит неудачу, когда присутствует несколько знаков «#» (сохраняя ведущие «#»)?
Это потому, что ". *" Является жадным, и будет соответствовать столько, сколько может.
У вашего сопоставителя должен быть метод, похожий на 'group (...)'. Большинство совпадений
вернуть всю подобранную последовательность как группу (0), первую подобранную группу как группу (1),
и пр.
PCRE настолько важен, что я настоятельно рекомендую вам найти его в Google, изучить его и всегда иметь в своем наборе инструментов программирования.