2

テキストからのトークンを正規表現と照合する必要があります。

Hello {FullName}, I wanted to inform that your product {ProductName} is ready.
Please come to our address {Address} to get it!

テキスト内の特定のトークンを照合し、正規表現を使用して値を入力するにはどうすればよいですか?

また、安全な方法でそれを行う必要があり、次のように、トークンのスペルが間違っていたり、何か問題があったりする可能性のあるすべての問題を回避する必要があります。

**Hello {Full{Name}, I { wanted to inform that your product {{ProductName} is ready.
Please come to our } address {Addr{Street}ess} to get it!**

PS

私はこれを試しました:{([^}]+)}

しかし、たとえば次の場合:

 {FullName}   

それは機能しますが、私が持っていても機能します

{Full{Name} ...

PS 2:

私はこれを試しました:{=[^{^=^}]*=} しかし、中括弧だけでなく別の文字を使用する必要があります...これが等しい文字なしで機能するように調整することは可能ですか?

 {=FullName=}    - this works
 {=Full{Name=}   - this doesn't work

したがって、基本的にトークン{=Token=}{Token}

4

3 に答える 3

2

バランシング グループ定義を使用できます。

class Program
{
    static void Main(string[] args)
    {
        string rawInput = @"**Hello {Full{Name}, I { wanted to 
            inform that your product {{ProductName} is ready.
            Please come to our } address {Addr{Street}ess} to get it!**";

        string pattern = "^[^{}]*" +
                       "(" +
                       "((?'Open'{)[^{}]*)+" +
                       "((?'Close-Open'})[^{}]*)+" +
                       ")*" +
                       "(?(Open)(?!))$";

        var tokens = Regex.Match(
            Regex.Match(rawInput, @"{[\s\S]*}").Value,
            pattern,
            RegexOptions.Multiline)
                .Groups["Close"]
                .Captures
                .Cast<Capture>()
                .Where(c =>
                    !c.Value.Contains('{') &&
                    !c.Value.Contains('}'))
                .ToList();

        tokens.ForEach(c =>
        {
            Console.WriteLine(c.Value);
        });
    }
}

上記の出力:

ProductName
Street
于 2013-08-08T15:03:46.317 に答える
2

これが出発点になるかもしれません。必要に応じて例外を処理します。

このメソッドは入力文字列を移動し、OpenToken が見つかったときに「open」フラグとインデックスを設定します。「open」フラグが true で、CloseToken が見つかった場合、インデックスと現在の位置に基づいて部分文字列を抽出します。

ThrowOnError プロパティが true に設定されていて、予期しない場所でトークンが見つかった場合、例外がスローされます。

このコードは、予期しないトークンを別の方法で処理するように簡単に変更できます...たとえば、一致を完全にスキップしたり、一致をそのまま追加したり、必要なものを何でも追加したりできます。

public class CustomTokenParser
{
    public char OpenToken { get; set; }
    public char CloseToken { get; set; }

    public bool ThrowOnError { get; set; }

    public CustomTokenParser()
    {
        OpenToken = '{';
        CloseToken = '}';
        ThrowOnError = true;
    }

    public CustomTokenParser(char openToken, char closeToken, bool throwOnError)
    {
        this.OpenToken = openToken;
        this.CloseToken = closeToken;
        this.ThrowOnError = throwOnError;
    }        

    public string[] Parse(string input)
    {
        bool open = false;
        int openIndex = -1;
        List<string> matches = new List<string>();

        for (int i = 0; i < input.Length; i++)
        {
            if (!open && input[i] == OpenToken)
            {
                open = true;
                openIndex = i;
            }
            else if (open && input[i] == CloseToken)
            {
                open = false;
                string match = input.Substring(openIndex + 1, i - openIndex - 1);
                matches.Add(match);
            }
            else if (open && input[i] == OpenToken && ThrowOnError)
                throw new Exception("Open token found while match is open");
            else if (!open && input[i] == CloseToken && ThrowOnError)
                throw new Exception("Close token found while match is not open");
        }

        return matches.ToArray();
    }
}
于 2013-08-08T14:49:43.250 に答える
0

この正規表現を使用して、90%動作させました:

Regex rx = new Regex("{=[^{^=^}^<^>]*=}");

ただし、これは私のトークンと一致し{= =}ます{ }

このようなトークン{=FullName=}がある場合、実際の名前に置き換えられますが、トークンが{=Full{Name=}間違っているため置き換えられず、無視される場合...これがアイデアです...今、どのように使用できますかただ{ }

于 2013-08-08T14:41:26.883 に答える