[英]Generate all matches for regex
對於用戶選擇,我想提供一個與給定正則表達式匹配的數字列表。 正則表達式本身非常簡單,只能看起來像這樣123 [0-9] [0-9]或[4-9] 34.2
我發現Fare ( https://github.com/moodmosaic/Fare )正在以某種方式完成這項工作。 請參見以下示例:
string pattern = "123[0-9][0-9]";
var xeger = new Xeger(pattern);
var match = xeger.Generate(); //match is e.g. "12349"
不幸的是,Fare-lib僅給我一個可能的匹配,但並不是字符串可以具有的所有100種可能的組合。
如果您認為regex在這種情況下不是一個好主意,而是建議使用for循環實現來替換char,那么我也打算這樣做,但目前我不知道該怎么做? 也許遞歸函數會很聰明?
我寧願創建自己的實現,也不願使用庫。 以下代碼可以實現您想要的功能。
private static Regex regexRegex = new Regex("\\[(?<From>\\d)-(?<To>\\d)]", RegexOptions.Compiled);
private static IEnumerable<string> GetStringsForRegex(string pattern)
{
var strings = Enumerable.Repeat("", 1);
var lastIndex = 0;
foreach (Match m in regexRegex.Matches(pattern))
{
if (m.Index > lastIndex)
{
var capturedLastIndex = lastIndex;
strings = strings.Select(s => s + pattern.Substring(capturedLastIndex, m.Index - capturedLastIndex));
}
int from = int.Parse(m.Groups["From"].Value);
int to = int.Parse(m.Groups["To"].Value);
if (from > to)
{
throw new InvalidOperationException();
}
strings = strings.SelectMany(s => Enumerable.Range(from, to - from + 1), (s, i) => s + i.ToString());
lastIndex = m.Index + m.Length;
}
if (lastIndex < pattern.Length)
{
var capturedLastIndex = lastIndex;
strings = strings.Select(s => s + pattern.Substring(capturedLastIndex));
}
return strings;
}
基本上,代碼構造了正則表達式模式的所有解決方案。 它甚至按字母順序計算它們。
當心capturedLastIndex
變量。 這是必需的,因為編譯器否則會捕獲lastIndex變量,從而導致錯誤的結果。
這是我現在為我工作的代碼。 不是很通用,並且僅適用於字符串中的兩個可能的表達式,但是它有效;)
List<string> possibleMatches = new List<string>();
string expression = "123?[3-9]" //this is an example
if (expression.Contains("?") || expression.Contains("["))
{
int count = expression.Count(f => f == '?');
count += expression.Count(f => f == '[');
if (count <= 2)
{
string pattern = expression.Replace('*', '.').Replace('?', '.');
pattern = pattern.Replace(".", "[0-9]");
int pos1 = pattern.IndexOf('[');
int start1 = Convert.ToInt32(pattern[pos1 + 1].ToString());
int end1 = Convert.ToInt32(pattern[pos1 + 3].ToString());
int pos2 = 0;
int start2, end2 = 0;
if (count > 1)
{
pos2 = pattern.IndexOf('[', pos1);
start2 = Convert.ToInt32(pattern[pos2 + 1].ToString());
end2 = Convert.ToInt32(pattern[pos2 + 3].ToString());
pattern = pattern.Remove(pos1, "[0-9]".Length);
pattern = pattern.Remove(pos2, "[0-9]".Length);
string copy = pattern;
for (int i = start1; i <= end1; i++)
{
copy = pattern.Insert(pos1, i.ToString());
for (int y = start2; y <= end2; y++)
{
possibleMatches.Add(copy.Insert(pos2, y.ToString()));
}
}
}
else
{
pattern = pattern.Remove(pos1, "[0-9]".Length);
for (int i = start1; i <= end1; i++)
{
possibleMatches.Add(pattern.Insert(pos1, i.ToString()));
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.