简体   繁体   English

在花括号之间匹配正则表达式

[英]Match regex between curly braces

I need to match with regular expression the tokens from text: 我需要用正则表达式匹配文本中的标记:

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

How can I match the specific tokens in my text and fill the values using regex? 如何匹配文本中的特定标记并使用正则表达式填充值?

Also I need to do it in a safe way and avoid every possible issues where the tokens my by misspelled or have something wrong, like bellow: 另外,我还需要以安全的方式进行操作,并避免出现以下所有可能的问题:令牌my可能拼写错误或出现错误,例如波纹管:

**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 PS

I tried this: {([^}]+)} 我试过了: {([^}]+)}

But if I have for example : 但是如果我有例如:

 {FullName}   

it works, but it also work if I have 它可以工作,但是如果我有也可以

{Full{Name} ...

PS 2: PS 2:

I tried this: {=[^{^=^}]*=} but I have to use another character instead of just curly braces ... is it possible to adjust it so that this will work without the equal character? 我试过这样的方法: {=[^{^=^}]*=}但我必须使用其他字符而不只是花括号...是否有可能对其进行调整,以使其在没有相同字符的情况下起作用?

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

So basically the token is between {=Token=} instead of {Token} 因此,基本上令牌位于{=Token=}而不是{Token}

This might give you a starting point. 这可能会给您一个起点。 Handle the exceptions however you'd like. 根据需要处理异常。

The method travels through the input string, setting an 'open' flag and index when it finds the OpenToken. 该方法遍历输入字符串,并在找到OpenToken时设置“ open”标志和索引。 When the 'open' flag is true, and a CloseToken is found, it extracts a substring based on the index and current position. 当'open'标志为true,并且找到CloseToken时,它将根据索引和当前位置提取一个子字符串。

If the ThrowOnError property is set to true, and a token is found in an unexpected location, it will throw an exception. 如果ThrowOnError属性设置为true,并且在意外位置发现了令牌,则它将引发异常。

This code could easily be modified to handle the unexpected tokens differently... such as skipping that match entirely, adding the match as-is, or whatever you desire. 可以轻松地修改此代码,以不同方式处理意外的令牌……例如完全跳过匹配项,按原样添加匹配项或您想要的任何内容。

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();
    }
}

You may use Balancing Group Definitions : 您可以使用平衡组定义

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);
        });
    }
}

The above outputs: 以上输出:

ProductName
Street

I kinda made it work 90% using this regex: 我使用这个正则表达式使它工作了90%:

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

however, this matches my token between {= =} instead of just { } 但是,这与我的令牌在{= =}之间匹配,而不仅仅是{ }

If I have a token like this {=FullName=} , it will be replaces with the actual name, but if the token is {=Full{Name=} it will not be replaced because is incorrect and will be ignored ... this is the idea ... now, how can I use just { } ? 如果我有一个像这样的令牌{=FullName=} ,它将被替换为实际名称,但是如果令牌是{=Full{Name=} ,它将不会被替换,因为它是不正确的,并且将被忽略……这是这个主意...现在,我怎么能只使用{ }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM