Если вам действительно нужна версия регулярного выражения, вы можете использовать шаблон следующим образом.
"(?<searchTerm>!)(?=(?:[^\"]|\"[^\"]*\")*$)"
Пример, для ввода
var input = new []
{
new {Key= "!something", BeginIndex=0},
new {Key= "!", BeginIndex=0},
new {Key= "something!", BeginIndex=0},
new {Key= "\"something!\"", BeginIndex=0},
new {Key= "\"some!thing\"!", BeginIndex=0},
new {Key= "!\"!\"!", BeginIndex=0},
new {Key= "\"\"!", BeginIndex=0},
new {Key= "\"\"!\"\"", BeginIndex=0},
new {Key= "!something", BeginIndex=2},
new {Key= "!something!", BeginIndex=2},
new {Key="!\"some!thing\"!",BeginIndex=5}
};
Вы можете искать в индексе следующим образом
var pattern = "(?<searchTerm>!)(?=(?:[^\"]|\"[^\"]*\")*$)";
Regex regex = new Regex(pattern,RegexOptions.Compiled);
foreach(var str in input)
{
var index = str.Key.GetIndex(regex,str.BeginIndex);
Console.WriteLine($"String:{str.Key} , Index : {index}");
}
Где GetIndex определяется как
public static class Extension
{
public static int GetIndex(this string source,Regex regex,int beginIndex=0)
{
var match = regex.Match(source);
while(match.Success)
{
if(match.Groups["searchTerm"].Index >= beginIndex)
return match.Groups["searchTerm"].Index;
match = match.NextMatch();
}
return -1;
}
}
выход
String:!something , Index : 0
String:! , Index : 0
String:something! , Index : 9
String:"something!" , Index : -1
String:"some!thing"! , Index : 12
String:!"!"! , Index : 0
String:""! , Index : 2
String:""!"" , Index : 2
String:!something , Index : -1
String:!something! , Index : 10
String:!"some!thing"! , Index : 13
Надеюсь, это поможет.