繁体   English   中英

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

[英]Match regex between curly braces

我需要用正则表达式匹配文本中的标记:

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

如何匹配文本中的特定标记并使用正则表达式填充值?

另外,我还需要以安全的方式进行操作,并避免出现以下所有可能的问题:令牌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

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

但是如果我有例如:

 {FullName}   

它可以工作,但是如果我有也可以

{Full{Name} ...

PS 2:

我试过这样的方法: {=[^{^=^}]*=}但我必须使用其他字符而不只是花括号...是否有可能对其进行调整,以使其在没有相同字符的情况下起作用?

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

因此,基本上令牌位于{=Token=}而不是{Token}

这可能会给您一个起点。 根据需要处理异常。

该方法遍历输入字符串,并在找到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();
    }
}

您可以使用平衡组定义

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

我使用这个正则表达式使它工作了90%:

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

但是,这与我的令牌在{= =}之间匹配,而不仅仅是{ }

如果我有一个像这样的令牌{=FullName=} ,它将被替换为实际名称,但是如果令牌是{=Full{Name=} ,它将不会被替换,因为它是不正确的,并且将被忽略……这是这个主意...现在,我怎么能只使用{ }

暂无
暂无

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

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