我正在尝试使用某种数据对象(我在想字典)来保存正则表达式的TON作为键,然后我需要获取一串文本,然后匹配它们以获得实际值来自字典。我需要一种有效的方法来处理大量数据。
我在C#,我不知道从哪里开始。
答案 0 :(得分:8)
为什么不使用LINQ?
Dictionary<string, string> myCollection = new Dictionary<string, string>();
myCollection.Add("(.*)orange(.*)", "Oranges are a fruit.");
myCollection.Add("(.*)apple(.*)", "Apples have pips.");
myCollection.Add("(.*)dog(.*)", "Dogs are mammals.");
// ...
string input = "tell me about apples and oranges";
var results = from result in myCollection
where Regex.Match(input, result.Key, RegexOptions.Singleline).Success
select result;
foreach (var result in results)
{
Console.WriteLine(result.Value);
}
// OUTPUT:
//
// Oranges are a fruit.
// Apples have pips.
答案 1 :(得分:0)
我不确定你是否真的需要正则表达式 - 你可以使用trie。代表字典是trie的常见应用。 (我假设你的意思是字词列表中的字典,而不是“关联数组”的意思)。
答案 2 :(得分:0)
你的意思是匹配正则表达式的字符串以获得正则表达式匹配?或者只是文字匹配?换句话说,你要成为其中一个正则表达式的字符串,还是要将正则表达式应用到的一些数据?
如果它是一个正则表达式并且你想在列表中找到它,你不需要一个字典,那些是2部分容器。您可以使用List或StringCollection,并询问IndexOf(mytString),-1表示它不在那里。
答案 3 :(得分:0)
如果您的正则表达式不是简单的单字符串,并且您关心效率,那么您需要在单个NFA (nondeterministic finite-state automaton中表示它们,其值为最终状态。如果输入可能匹配多个正则表达式,那么最终状态将需要一组值。
此时,您已准备好考虑优化自动机。如果它可以实际确定(这给你一个可以指数大于NFA的DFA),那么一定要做到这一点。一旦你有了DFA,你就可以有效地(并且唯一地达到同构)最小化它(但是因为你在最终状态中有值,所以需要对usual algorithm进行明显的修改。)
还有一些技术可以直接减少NFA。例如,如果两个状态具有相同的后缀集({(其余字符串,值)}),则它们是等效的并且可以组合。非循环NFA中的等价可以从最终状态开始通过hash-consing完成。
答案 4 :(得分:0)
请记住,如果您计划多次使用正则表达式,则可以在编译时创建正则表达式对象并重新使用它以减少开销。
Regex RegexObject = new Regex(Pattern, RegexOptions.Compiled);
使用此模型最好存储正则表达式对象而不是模式字符串。
答案 5 :(得分:0)
以下回购中有一个RegexPatternDictionaryImpl
类型,可用于将正则表达式存储为键,并将所需的任何值存储为值。不过,该词典并未针对性能进行优化。它只是对键进行线性扫描,并将它们与给定的字符串匹配,以返回所有匹配的值。但是,对于较小的用例,此字典就足够了:
字典相对稳定,在此处编写了许多测试:
如果您想自己编写代码,以下是编写此答案时的源代码快照。注意:您可能必须解开库的某些方面才能使用此功能:
namespace CsharpExtras.Dictionary
{
public class RegexPatternDictionaryImpl<TValue> :
IRegexPatternDictionary<TValue>
{
private readonly IDictionary<string, TValue> _baseDictionary;
private readonly IDictionary<Regex, string> _regexDictionary;
public RegexPatternDictionaryImpl()
{
_baseDictionary = new Dictionary<string, TValue>();
_regexDictionary = new Dictionary<Regex, string>();
}
public void Add(string pattern, TValue value)
{
AddRegexToDictionary(pattern, pattern, value);
}
public ICollection<TValue> FindAllValuesThatMatch(string textKey)
{
ICollection<TValue> result = new List<TValue>();
foreach (var item in _regexDictionary.Where(r => r.Key.IsMatch(textKey)))
{
result.Add(_baseDictionary[item.Value.ToString()]);
}
return result;
}
public bool HasMatch(string textKey)
{
return _regexDictionary.Any(r => r.Key.IsMatch(textKey));
}
public ICollection<(string pattern, TValue values)> FindAllPatternValuePairsThatMatch(string textKey)
{
ICollection<(string pattern, TValue values)> result = new List<(string pattern, TValue values)>();
foreach (KeyValuePair<Regex, string> item in _regexDictionary.Where(r => r.Key.IsMatch(textKey)))
{
result.Add((item.Key.ToString(), _baseDictionary[item.Value.ToString()]));
}
return result;
}
public void AddEscapedFullMatchPattern(string pattern, TValue value)
{
string escapedPattern = Regex.Escape(pattern);
string fullMatchPattern = MakePatternMatchFullString(escapedPattern);
AddRegexToDictionary(fullMatchPattern, pattern, value);
}
public void AddFullMatchPattern(string pattern, TValue value)
{
string fullMatchPattern = MakePatternMatchFullString(pattern);
AddRegexToDictionary(fullMatchPattern, pattern, value);
}
#region Base dictionary methods
public TValue this[string key] { get => _baseDictionary[key]; set => _baseDictionary[key] = value; }
public ICollection<string> Keys => _baseDictionary.Keys;
public ICollection<TValue> Values => _baseDictionary.Values;
public int Count => _baseDictionary.Count;
public bool IsReadOnly => _baseDictionary.IsReadOnly;
public void Add(KeyValuePair<string, TValue> item)
{
_baseDictionary.Add(item);
}
public void Clear()
{
_baseDictionary.Clear();
}
public bool Contains(KeyValuePair<string, TValue> item)
{
return _baseDictionary.Contains(item);
}
public bool ContainsKey(string key)
{
return _baseDictionary.ContainsKey(key);
}
public void CopyTo(KeyValuePair<string, TValue>[] array, int arrayIndex)
{
_baseDictionary.CopyTo(array, arrayIndex);
}
public IEnumerator<KeyValuePair<string, TValue>> GetEnumerator()
{
return _baseDictionary.GetEnumerator();
}
public bool Remove(string key)
{
return _baseDictionary.Remove(key);
}
public bool Remove(KeyValuePair<string, TValue> item)
{
return _baseDictionary.Remove(item);
}
public bool TryGetValue(string key, out TValue value)
{
return _baseDictionary.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return _baseDictionary.GetEnumerator();
}
#endregion
private void AddRegexToDictionary(string actualPattern, string keyPattern, TValue value)
{
Regex regex = new Regex(actualPattern, RegexOptions.Compiled);
_baseDictionary.Add(keyPattern, value);
_regexDictionary.Add(regex, keyPattern);
}
private string MakePatternMatchFullString(string pattern)
{
string updatedPattern = pattern;
if (!pattern.StartsWith("^"))
{
updatedPattern = "^" + updatedPattern;
}
if (!pattern.EndsWith("$"))
{
updatedPattern += "$";
}
return updatedPattern;
}
}
}
上述存储库由我在我的个人GitHub网站上维护。