#c# #regex #string #pattern-matching
#c# #регулярное выражение #строка #сопоставление с шаблоном
Вопрос:
Я пытаюсь проверить программу, которую я создаю, на будущее, чтобы шаблон, который мне нужен для ввода пользователями, не был жестко закодирован. Всегда есть вероятность, что скороговорка с буквами или цифрами может измениться, но когда это произойдет, мне нужно, чтобы все оставались последовательными. Кроме того, я хочу, чтобы менеджеры контролировали то, что поступает, не полагаясь на меня. Возможно ли использовать регулярное выражение или другой инструмент для сравнения ввода со списком, хранящимся в базе данных. Я хочу, чтобы это было легко, чтобы шаблоны, хранящиеся в базе данных, выглядели как X ###### или X ######-X ######## и так далее.
Комментарии:
1. Вероятно, вы можете использовать маски (своего рода регулярные выражения) вместо реальных регулярных выражений: см. msdn.microsoft.com/en-us/library/… Их можно использовать в текстовых полях, чтобы пользователи могли вводить только правильный текст.
2. Это форма WPF или Win? Пожалуйста, добавьте больше деталей к вашему требованию. Rgds,
Ответ №1:
Конечно, просто сохраните правила регулярных выражений в столбце string в таблице, а затем загрузите их в IEnumerable<Regex>
в вашем приложении. Тогда совпадение — это просто совпадение ЛЮБОГО из этих правил. Имейте в виду, что конфликтующие правила могут быть склонны к жадной гонке (выигрывает первое, которое будет проверено), поэтому вам нужно быть осторожным. Также имейте в виду, что существует множество оптимизаций, которые вы могли бы выполнить помимо моего примера, который разработан так, чтобы быть простым.
List<string> regexStrings = db.GetRegexStrings();
var result = new List<Regex>(regexStrings.Count);
foreach (var regexString in regexStrings)
{
result.Add(new Regex(regexString);
}
...
// The check
bool matched = result.Any(i => i.IsMatch(testInput));
Комментарии:
1. Этот пример действительно работает, но как мне заставить его работать более динамично. Возвращается значение true, если входные данные имеют значение X # ##, а база данных имеет значение X ###. Однако я хочу, чтобы X # ## было истинным для X123, но ложным для X1234. Этот тип сравнения.
2. Кроме того, я надеялся, что база данных действительно будет содержать «X # # #». Я знаю, что в Excel вы можете создавать пользовательские поля, подобные этому
3. Вы бы использовали ограничения регулярных выражений… Существуют способы ограничить входные данные для сопоставления. Вам нужно будет немного поискать в Google, чтобы узнать о способах ограничения ввода регулярных выражений.
Ответ №2:
Вы могли бы сохранить свои шаблоны как есть в своей базе данных, а затем преобразовать их в регулярные выражения.
Я не знаю конкретно, какие символы вам понадобятся в вашем формате, но давайте предположим, что вы просто хотите заменить число на #
и оставить остальное как есть, вот некоторый код для этого:
public static Regex ConvertToRegex(string pattern)
{
var sb = new StringBuilder();
sb.Append("^");
foreach (var c in pattern)
{
switch (c)
{
case '#':
sb.Append(@"d");
break;
default:
sb.Append(Regex.Escape(c.ToString()));
break;
}
}
sb.Append("$");
return new Regex(sb.ToString());
}
Вы также можете использовать такие параметры, как RegexOptions.IgnoreCase
если это то, что вам нужно.
ПРИМЕЧАНИЕ: По какой-то причине Regex.Escape
экранирует #
символ, даже если он не является особенным… Поэтому я просто выбрал посимвольный подход.
Ответ №3:
private bool TestMethod()
{
const string textPattern = "X###";
string text = textBox1.Text;
bool match = true;
if (text.Length == textPattern.Length)
{
char[] chrStr = text.ToCharArray();
char[] chrPattern = textPattern.ToCharArray();
int length = text.Length;
for (int i = 0; i < length; i )
{
if (chrPattern[i] != '#')
{
if (chrPattern[i] != chrStr[i])
{
return false;
}
}
}
}
else
{
return false;
}
return match;
}
Это делает все, что мне нужно сейчас. Тем не менее, спасибо за все советы. В будущем мне придется подробнее изучить регулярное выражение.
Ответ №4:
Используя MaskedTextProvider
, вы могли бы сделать что-то вроде этого:
using System.Globalization;
using System.ComponentModel;
string pattern = "Xamp;amp;amp;amp;amp;amp;-Xamp;amp;amp;amp;amp;amp;amp;";
string text = "Xabcdef-Xasdfghi";
var culture = CultureInfo.GetCultureInfo("sv-SE");
var matcher = new MaskedTextProvider(pattern, culture);
int position;
MaskedTextResultHint hint;
if (!matcher.Set(text, out position, out hint))
{
Console.WriteLine("Error at {0}: {1}", position, hint);
}
else if (!matcher.MaskCompleted)
{
Console.WriteLine("Not enough characters");
}
else if (matcher.ToString() != text)
{
Console.WriteLine("Missing literals");
}
else
{
Console.WriteLine("OK");
}
Описание формата см.:http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.mask