Это немного уродливо с Regex, но вот оно:
var str = @"line 1 //comment
line2; test;
extra text; //comment may also contain ;.";
var matches = Regex.Matches(str, @"^(?:(?<!//).)+(;)", RegexOptions.Multiline);
if (matches.Count > 0)
{
Console.WriteLine(matches[matches.Count - 1].Groups[1].Index);
}
Мы получаем совпадение для последней точки с запятой в каждой строке (которой не предшествует комментарий), затем мы смотрим напоследнее из этих совпадений.
Мы должны делать это построчно, так как комментарии применяются ко всей строке.
Если вы хотите обрабатывать каждую строку отдельно (вашвопрос не говорит об этом, но это подразумевает это), затем переберите matches
вместо того, чтобы просто смотреть на последний.
Если вы хотите заменить каждую точку с запятой другим символом, тогда вы можете сделать что-тонапример:
const string replacement = "#";
var result = Regex.Replace(str, @"^((?:(?<!//).)+);", "$1" + replacement, RegexOptions.Multiline);
Если вы хотите полностью удалить его, просто:
var result = Regex.Replace(str, @"^((?:(?<!//).)+);", "$1", RegexOptions.Multiline);
Если вы просто хотите удалить последнюю точку с запятой во всей строке, вы можете простоиспользуйте string.Remove
:
var matches = Regex.Matches(str, @"^(?:(?<!//).)+(;)", RegexOptions.Multiline);
if (matches.Count > 0)
{
str = str.Remove(matches[matches.Count - 1].Groups[1].Index, 1);
}