C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.99776 の関連記事表示

<< 0 >>
■99776  Re[10]: 正規表現で文字列の否定
□投稿者/ 匿名希望マン -(2022/05/29(Sun) 14:48:42)
    お久しぶりです。能力が足りないので、時間がかかっています。
    
    以下計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?)))))))?)?$
    
記事No.99465 のレス / END /過去ログ173より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -