我正在寻找正则表达式来执行以下操作:
int startIndex
位置开始速度是我这里主要关注的问题之一,因此迭代次数应尽可能少。
示例(所有示例都设置为寻找!
,但这并非总是如此):
!something
-应该返回0 !
也应返回0 something!
应该返回9 "something!"
应该失败"some!thing"!
应该返回12 !"!"!
应该返回0 ""!
应该返回2 ""!""
应该返回2 !something
和startIndex == 2
应该失败!something!
与startIndex == 2
应该返回10(尽管从位置2开始,给定字符串上字符的索引仍然是10)因为这是.NET的用意,所以将使用Regex.Match().Index
(除非提供了更好的替代方法)。
答案 0 :(得分:1)
我建议使用旧的for
循环,而不要使用正则表达式;让我们将其实现为扩展方法:
public static partial class StringExtensions {
public static int IndexOfQuoted(this string value,
char toFind,
int startPosition = 0,
char quotation = '"') {
if (string.IsNullOrEmpty(value))
return -1;
bool inQuotation = false;
for (int i = 0; i < value.Length; ++i)
if (inQuotation)
inQuotation = value[i] != quotation;
else if (value[i] == toFind && i >= startPosition)
return i;
else
inQuotation = value[i] == quotation;
return -1;
}
}
因此,您可以像使用IndexOfQuoted
的{{1}}方法一样使用它:
string
演示:
string source = "something!";
int result = source.IndexOfQuoted('!');
结果:
string[] tests = new string[] {
"!something",
"!",
"something!",
"\"something!\"",
"\"some!thing\"!",
"!\"!\"!",
"\"\"!",
"\"\"!\"\"",
};
string report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,-20} -> {test.IndexOfQuoted('!')}"));
Console.Write(report);
答案 1 :(得分:0)
如果您确实需要正则表达式版本,则可以使用以下模式。
"(?<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
希望有帮助。