4

次の文字列をこれに分割しようとしています"Name=='mynme' && CurrentTime<'2012-04-20 19:45:45'":

Name
==
'myname'
&&
CurrentTime
<
'2012-04-20 19:45:45'

次の正規表現があります。

([+\\-*/%()]{1}|[=<>!]{1,2}|[&|]{2})

問題は、上記の正規表現を使用すると、次の結果が得られることです。

Name
== 
'myname'
&&
CurrentTime 
<
'2012
-
04
-
20
19:45:45'

実際には、正規表現を引用符で認識する必要があります。

ありがとう

lordcheeto の回答に関する更新 1:

あなたの反応は近いです。しかし、以下はまだ正しく分割されていません:

 string input2 = "((1==2) && 2-1==1) || 3+1==4 && Name=='Stefan+123'";

私がする必要があるのは、文字列を演算子とオペランドに分割することです。このようなもの:

 LeftOperand Operator RightOperand

これで、間に演算子がある場合は''無視され、間にある文字列全体が''オペランドとして扱われます。

上記の文字列は、次の出力を生成する必要があります。

(

(
1
==
2
)

&&
2
-
1
==
1
)

||
3
+
1
==
4
&&
Name
==
'Stefan+123'
4

2 に答える 2

3

論理演算子と関係演算子で単純に分割したい場合は、次のパターンを使用できます。

string lordcheeto = @"\s*(==|&&|<=|>=|<|>)\s*";    

これにより、返された文字列からすべての空白も削除されます。

コード:

using System;
using System.Text.RegularExpressions;

namespace RegEx
{
    class Program
    {
        static void Main(string[] args)
        {
            string original = "([+\\-*/%()]{1}|[=<>!]{1,2}|[&|]{2})";
            string lordcheeto = @"\s*(==|&&|<=|>=|<|>)\s*";

            string input = "Name=='mynme' && CurrentTime<45 - 4";
            string input1 = "Name=='mynme' && CurrentTime<'2012-04-20 19:45:45'";
            string ridiculous = "Name == BLAH && !@#>=$%^&*()< ASDF &&    this          >          that";

            executePattern("original", input, original);
            executePattern("lordcheeto's", input, lordcheeto);
            executePattern("original", input1, original);
            executePattern("lordcheeto's", input1, lordcheeto);
            executePattern("original", ridiculous, original);
            executePattern("lordcheeto's", ridiculous, lordcheeto);
        }

        static void executePattern(string version, string input, string pattern)
        {
            // Avoiding repitition for this example.
            Console.WriteLine("Using {0} pattern:", version);

            // Needs to be trimmed.
            var result = Regex.Split(input.Trim(), pattern);

            // Pipes included to highlight whitespace trimming.
            foreach (var m in result)
                Console.WriteLine("|{0}|", m);

            // Extra space.
            Console.WriteLine();
            Console.WriteLine();
        }
    }
}

テスト:

http://goo.gl/XAm6J

出力:

Using original pattern:
|Name|
|==|
|'mynme' |
|&&|
| CurrentTime|
|<|
|45 |
|-|
| 4|


Using lordcheeto's pattern:
|Name|
|==|
|'mynme'|
|&&|
|CurrentTime|
|<|
|45 - 4|


Using original pattern:
|Name|
|==|
|'mynme' |
|&&|
| CurrentTime|
|<|
|'2012|
|-|
|04|
|-|
|20 19:45:45'|


Using lordcheeto's pattern:
|Name|
|==|
|'mynme'|
|&&|
|CurrentTime|
|<|
|'2012-04-20 19:45:45'|


Using original pattern:
|Name |
|==|
| BLAH |
|&&|
| |
|!|
|@#|
|>=|
|$|
|%|
|^&|
|*|
||
|(|
||
|)|
||
|<|
| ASDF |
|&&|
|    this          |
|>|
|          that|


Using lordcheeto's pattern:
|Name|
|==|
|BLAH|
|&&|
|!@#|
|>=|
|$%^&*()|
|<|
|ASDF|
|&&|
|this|
|>|
|that|

編集

わかりました、追加の制約により、これを使用できるはずです:

string lordcheeto = @"\s*('.*?'|&&|==|<=|>=|<|>|\(|\)|\+|-|\|\|)\s*";

これにより、返された文字列からすべての空白が削除されます。ただし、一致が互いに隣接している場合は空の文字列が返されます (例: Name=='Stefan+123')。今回はそれを回避できませんでしたが、それほど重要ではありません。

インポートSystem.LinqSystem.Collections.Genericて結果を aList<string>にすると、次のように 1 行余分に からすべての空の文字列を削除できますList(単純な for ループを使用するよりも遅くなります)。

var results = Regex.Split(input.Trim(), pattern).ToList();
results.RemoveAll(x => x == "");

コード:

using System;
using System.Text.RegularExpressions;

namespace RegEx
{
    class Program
    {
        static void Main(string[] args)
        {
            string lordcheeto = @"\s*('.*?'|&&|==|<=|>=|<|>|\(|\)|\+|-|\|\|)\s*";

            string input = "Name=='mynme' && CurrentTime<45 - 4";
            string input1 = "Name=='mynme' && CurrentTime<'2012-04-20 19:45:45'";
            string input2 = "((1==2) && 2-1==1) || 3+1==4 && Name=='Stefan+123'";

            executePattern("lordcheeto's", input, lordcheeto);
            executePattern("lordcheeto's", input1, lordcheeto);
            executePattern("lordcheeto's", input2, lordcheeto);

            Console.ReadLine();
        }

        static void executePattern(string version, string input, string pattern)
        {
            // Avoiding repitition for this example.
            Console.WriteLine("Using {0} pattern:", version);

            // Needs to be trimmed.
            var result = Regex.Split(input.Trim(), pattern);

            // Pipe included to highlight empty strings.
            foreach (var m in result)
                Console.WriteLine("|{0}", m);

            // Extra space.
            Console.WriteLine();
            Console.WriteLine();
        }
    }
}

テスト:

http://goo.gl/lkaoM

出力:

Using lordcheeto's pattern:
|Name
|==
|
|'mynme'
|
|&&
|CurrentTime
|<
|45
|-
|4


Using lordcheeto's pattern:
|Name
|==
|
|'mynme'
|
|&&
|CurrentTime
|<
|
|'2012-04-20 19:45:45'
|


Using lordcheeto's pattern:
|
|(
|
|(
|1
|==
|2
|)
|
|&&
|2
|-
|1
|==
|1
|)
|
|||
|3
|+
|1
|==
|4
|&&
|Name
|==
|
|'Stefan+123'
|

追加コメント:

<<他の演算子 ( 、 、+==-=など>>)で分割したい場合(たくさんあります)、または他に何か必要な場合は、お問い合わせください。

于 2012-04-21T04:35:21.490 に答える