| お久しぶりです。能力が足りないので、時間がかかっています。
以下計16個の正規表現
・文字列"0"を含まない任意の文字列とマッチする正規表現Regex01、
・文字列"01"を含まない任意の文字列とマッチする正規表現Regex02、
・文字列"012"を含まない任意の文字列とマッチする正規表現Regex03、
・...
・文字列"0123456789ABCDEF"を含まない任意の文字列とマッチする正規表現Regex16、
を例のサイトで生成して、それらのルールを分析して、C#のメソッド作ってみました。
ただし、改行文字とか対応してません。
internal static class RegexPatternGenerator
{
public static string GenerateNegativePattern(string ngWord)
{
if (string.IsNullOrEmpty(ngWord))
{
throw new Exception();
}
string head = ngWord[0].ToString();
if (ngWord.Length == 1)
{
return string.Format("[^{0}]*", head);
}
string part1 = Part1(ngWord);
string part2 = Part2(ngWord);
string part3 = Part3(ngWord);
string part4 = Part4(ngWord);
return string.Format("([^{0}]|{0}({1})*({2}))*(({3}){4})?", head, part1, part2, part3, part4);
}
private static string Part1(string ngWord)
{
if (ngWord.Length < 2)
{
throw new Exception();
}
char head = ngWord[0];
string result = head.ToString();
for (int i = ngWord.Length - 1; 2 <= i; i--)
{
result = string.Format("{0}|{1}({2})", head, ngWord[i - 1], result);
}
return result;
}
private static string Part2(string ngWord)
{
if (ngWord.Length < 2)
{
throw new Exception();
}
char head = ngWord[0];
string result = string.Format("[^{0}{1}]", head, ngWord[ngWord.Length - 1]);
for (int i = ngWord.Length - 1; 2 <= i; i--)
{
result = string.Format("[^{0}{1}]|{1}({2})", head, ngWord[i - 1], result);
}
return result;
}
private static string Part3(string ngWord)
{
if (ngWord.Length < 2)
{
throw new Exception();
}
else if (ngWord.Length == 1)
{
return string.Empty;
}
char head = ngWord[0];
string part1 = Part1(ngWord);
if (ngWord.Length == 2)
{
return string.Format("{0}*", part1);
}
else
{
return string.Format("{0}({1})*", head, part1);
}
}
private static string Part4(string ngWord)
{
if (ngWord.Length < 2)
{
throw new Exception();
}
else if (ngWord.Length == 2)
{
return string.Empty;
}
string result = string.Format("({0})?", ngWord[ngWord.Length - 2]);
for (int i = ngWord.Length - 1; 3 <= i; i--)
{
result = string.Format("({0}{1})?", ngWord[i - 2], result);
}
return result;
}
}
でも、本当にやりたいのは、こういう単なる文字列処理ではなく、決定性有限オートマトンから正規表現へ変換するアプローチなので、そちらも悩んで頑張って作ってみます!
できたらまた追記します!
ちなみに、生成して分析していた正規表現は以下です。
ルールが見えやすいように、正規表現の縦を合わせていますが、実際はスペースや改行はありません。
Regex01: ^[^0]*$
Regex02: ^([^0]|0+ [^01])* 0*$
Regex03: ^([^0]|0(0|10)* ([^01]|1[^02]))* (0(0|10)* 1?)?$
Regex04: ^([^0]|0(0|1(0|20))* ([^01]|1([^02]|2[^03])))* (0(0|1(0|20))* (12?)?)?$
Regex05: ^([^0]|0(0|1(0|2(0|30)))* ([^01]|1([^02]|2([^03]|3[^04]))))* (0(0|1(0|2(0|30)))* (1(2?|23))?)?$
Regex06: ^([^0]|0(0|1(0|2(0|3(0|40))))* ([^01]|1([^02]|2([^03]|3([^04]|4[^05])))))* (0(0|1(0|2(0|3(0|40))))* (1(2?|234?))?)?$
Regex07: ^([^0]|0(0|1(0|2(0|3(0|4(0|50)))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5[^06]))))))* (0(0|1(0|2(0|3(0|4(0|50)))))* (1(2?|23(4?|45)))?)?$
Regex08: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|60))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6[^07])))))))* (0(0|1(0|2(0|3(0|4(0|5(0|60))))))* (1(2?|23(4?|456?)))?)?$
Regex09: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|70)))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7[^08]))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|70)))))))* (1(2?|23(4?|45(6?|67))))?)?$
Regex10: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|80))))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8[^09])))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|80))))))))* (1(2?|23(4?|45(6?|678?))))?)?$
Regex11: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|90)))))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8([^09]|9[^0A]))))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|90)))))))))* (1(2?|23(4?|45(6?|67(8?|89)))))?)?$
Regex12: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A0))))))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8([^09]|9([^0A]|A[^0B])))))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A0))))))))))* (1(2?|23(4?|45(6?|67(8?|89A?)))))?)?$
Regex13: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B0)))))))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8([^09]|9([^0A]|A([^0B]|B[^0C]))))))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B0)))))))))))* (1(2?|23(4?|45(6?|67(8?|89(A?|AB))))))?)?$
Regex14: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B(0|C0))))))))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8([^09]|9([^0A]|A([^0B]|B([^0C]|C[^0D])))))))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B(0|C0))))))))))))* (1(2?|23(4?|45(6?|67(8?|89(A?|ABC?))))))?)?$
Regex15: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B(0|C(0|D0)))))))))))))* ([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8([^09]|9([^0A]|A([^0B]|B([^0C]|C([^0D]|D[^0E]))))))))))))))* (0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B(0|C(0|D0)))))))))))))* (1(2?|23(4?|45(6?|67(8?|89(A?|AB(C?|CD)))))))?)?$
Regex16: ^([^0]|0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B(0|C(0|D(0|E0))))))))))))))*([^01]|1([^02]|2([^03]|3([^04]|4([^05]|5([^06]|6([^07]|7([^08]|8([^09]|9([^0A]|A([^0B]|B([^0C]|C([^0D]|D([^0E]|E[^0F])))))))))))))))*(0(0|1(0|2(0|3(0|4(0|5(0|6(0|7(0|8(0|9(0|A(0|B(0|C(0|D(0|E0))))))))))))))*(1(2?|23(4?|45(6?|67(8?|89(A?|AB(C?|CDE?)))))))?)?$
|