Ответ сам.
Это проблема, связанная с связкой ключей, которая возникает, когда вы вызываете сервис через SSH.
There is text2re, a free web-based "regex by example" generator.
I don't think this is available in source code, though. I dare to say there is no automatic regex generator that gets it right without user intervention, since this would require the machine knowing what you want.
Note that text2re uses a template-based, modularized and very generalized approach to regular expression generation. The expressions it generates work, but they are much more complex than the equivalent hand-crafted expression. It is not a good tool to learn regular expressions because it does a pretty lousy job at setting examples.
For instance, the string "2009/11/12"
would be recognized as a yyyymmdd
pattern, which is helpful. The tool transforms it into this 125 character monster:
((?:(?:[1]{1}\d{1}\d{1}\d{1})|(?:[2]{1}\d{3}))[-:\/.](?:[0]?[1-9]|[1][012])[-:\/.](?:(?:[0-2]?\d{1})|(?:[3][01]{1})))(?![\d])
The hand-made equivalent would take up merely two fifths of that (50 characters):
([12]\d{3})[-:/.](0?\d|1[0-2])[-:/.]([0-2]?\d|3[01])\b
Невозможно написать общее решение для вашей проблемы. Проблема в том, что любой генератор, вероятно, не будет знать, что вы хотите проверить, например, следует ли разрешить "2312/45/67"? А как насчет «2009.11.12»?
Что вы можете сделать, так это написать такой генератор, который подходит именно для вашей проблемы, но общее решение не будет возможным.
Я попробовал очень наивный подход:
class RegexpGenerator {
public static Pattern generateRegexp(String prototype) {
return Pattern.compile(generateRegexpFrom(prototype));
}
private static String generateRegexpFrom(String prototype) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < prototype.length(); i++) {
char c = prototype.charAt(i);
if (Character.isDigit(c)) {
stringBuilder.append("\\d");
} else if (Character.isLetter(c)) {
stringBuilder.append("\\w");
} else { // falltrought: literal
stringBuilder.append(c);
}
}
return stringBuilder.toString();
}
private static void test(String prototype) {
Pattern pattern = generateRegexp(prototype);
System.out.println(String.format("%s -> %s", prototype, pattern));
if (!pattern.matcher(prototype).matches()) {
throw new AssertionError();
}
}
public static void main(String[] args) {
String[] prototypes = {
"2009/11/12",
"I'm a test",
"me too!!!",
"124.323.232.112",
"ISBN 332212"
};
for (String prototype : prototypes) {
test(prototype);
}
}
}
вывод:
2009/11/12 ->
Я тест -> \ w '\ w \ w \ w \ w \ w \ w
я тоже!!! -> \ w \ w \ w \ w \ w !!!
124.323.232.112 -> \ d \ d \ d. \ D \ d \ d. \ D \ d \ d. \ D \ d \ d
ISBN 332212 -> \ w \ w \ w \ w \ d \ d \ d \ d \ d \ d
Как уже отмечалось другими, общее решение этой проблемы невозможно. Этот класс применим только в нескольких контекстах
No, you cannot get a regex that matches what you want reliably, since the regex would not contain semantic information about the input (i.e. it would need to know it's generating a regex for dates). If the issue is with dates only I would recommend trying multiple regular expressions and see if one of them matches all.
I'm not sure if this is possible, at least not without many sample strings and some learning algorithm.
There are many regex' that would match and it's not possible for a simple algorithm to pick the 'right' one. You'd need to give it some delimiters or other things to look for, so you might as well just write the regex yourself.
звучит как проблема машинного обучения. Вам нужно будет иметь под рукой более одного примера (намного больше) и указывать, считается ли каждый пример совпадением или нет.
I don't remember the name but if my theory of computation cells serve me right its impossible in theory :)
Я не нашел ничего, что делает это, но, поскольку проблемная область относительно мала (вы будете удивлены, сколько людей используют самые странные форматы дат), Я смог написать что-то вроде «генератора регулярных выражений даты». Как только я буду удовлетворен модульными тестами, я опубликую его - на всякий случай, если кому-то когда-нибудь понадобится что-то подобное.
Спасибо всем, кто ответил (парень, за исключением (. *) - шутки замечательные. , но этот был sssssssssoooo хромой :))
Простите, но то, что вы все называете невозможным, явно достижимая задача. Он не сможет дать результаты для ВСЕХ примеров, и, возможно, не самые лучшие результаты, но вы можете дать ему различные подсказки, и это упростит жизнь. Далее следуют несколько примеров.
Также был бы очень полезен читаемый вывод, транслирующий результат. Примерно так:
Возможно, мы могли бы создать «обратный переводчик» с языком типа SQL для создания регулярного выражения, вместо того, чтобы создавать его на компьютерном языке.
Вот несколько примеров, которые можно выполнить:
class Hint:
Properties: HintType, HintString
enum HintType { Separator, ParamDescription, NumberOfParameters }
enum SampleType { FreeText, DateOrTime, Formatted, ... }
public string RegexBySamples( List<T> samples,
List<SampleType> sampleTypes,
List<Hint> hints,
out string GeneralRegExp, out string description,
out string generalDescription)...
regex = RegExpBySamples( {"11/November/1999", "2/January/2003"},
SampleType.DateOrTime,
new HintList( HintType.NumberOfParameters, 3 ));
regex = RegExpBySamples( "123-aaaaJ-1444",
SampleType.Format, HintType.Seperator, "-" );
Графический интерфейс, в котором вы помечаете образец текста или вводите его, также возможно добавление в регулярное выражение. Сначала вы отмечаете дату («образец») и выбираете, если этот текст уже отформатирован, или, если вы создаете формат, а также тип формата: свободный текст, форматированный текст, дата, GUID или Выбрать ... из существующих форматов (которые вы можете хранить в библиотеке).
Давайте разработаем для этого спецификацию и сделаем ее с открытым исходным кодом ... Кто-нибудь хочет присоединиться?
Лорето в значительной степени делает это. Это реализация с открытым исходным кодом, в которой используются самые длинные подстроки для генерации регулярных выражений. Хотя, конечно, требуется несколько примеров.