Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Regex,有没有更有效的方法来解析由符号括起的字符串?_C#_Regex_String - Fatal编程技术网

C#Regex,有没有更有效的方法来解析由符号括起的字符串?

C#Regex,有没有更有效的方法来解析由符号括起的字符串?,c#,regex,string,C#,Regex,String,我不确定是否可以问。。。但事情是这样的 我实现了一个使用regex解析字符串的方法,每个匹配都通过委托解析,并带有一个顺序(实际上,顺序并不重要——我想,等等,是吗?…但我是这样写的,它没有经过完全测试): Pattern Regex.Replace:@”(?我认为这是对这个问题的独特理解。您可以构建一个类,该类将用于逐块构造整个模式。该类将负责生成MatchEvaluator委托,该委托也将传递给Replace class RegexReplacer { public string

我不确定是否可以问。。。但事情是这样的

我实现了一个使用regex解析字符串的方法,每个匹配都通过委托解析,并带有一个顺序(实际上,顺序并不重要——我想,等等,是吗?…但我是这样写的,它没有经过完全测试):


  • Pattern Regex.Replace:
    @”(?我认为这是对这个问题的独特理解。您可以构建一个类,该类将用于逐块构造整个模式。该类将负责生成
    MatchEvaluator
    委托,该委托也将传递给
    Replace

    class RegexReplacer
    {
        public string Pattern { get; private set; }
        public string Replacement { get; private set; }
        public string GroupName { get; private set; }
        public RegexReplacer NextReplacer { get; private set; }
    
        public RegexReplacer(string pattern, string replacement, string groupName, RegexReplacer nextReplacer = null)
        {
            this.Pattern = pattern;
            this.Replacement = replacement;
            this.GroupName = groupName;
            this.NextReplacer = nextReplacer;
        }
    
        public string GetAggregatedPattern()
        {
            string constructedPattern = this.Pattern;
            string alternation = (this.NextReplacer == null ? string.Empty : "|" + this.NextReplacer.GetAggregatedPattern());   // If there isn't another replacer, then we won't have an alternation; otherwise, we build an alternation between this pattern and the next replacer's "full" pattern
    
            constructedPattern = string.Format("(?<{0}>{1}){2}", this.GroupName, this.Pattern, alternation);    // The (?<XXX>) syntax builds a named capture group. This is used by our GetReplacementDelegate metho.
    
            return constructedPattern;
        }
    
        public MatchEvaluator GetReplaceDelegate()
        {
            return (match) =>
            {
                if (match.Groups[this.GroupName] != null && match.Groups[this.GroupName].Length > 0)    // Did we get a hit on the group name?
                {
                    return this.Replacement;
                }
                else if (this.NextReplacer != null)                                                     // No? Then is there another replacer to inspect?
                {
                    MatchEvaluator next = this.NextReplacer.GetReplaceDelegate();
    
                    return next(match);
                }
                else
                {
                    return match.Value;                                                                 // No? Then simply return the value
                }
            };
        }
    }
    
    因为您希望每个替换程序都知道它是否成功,并且因为我们正在通过使用组名对此进行攻击,所以您希望确保每个组名都是不同的。确保这一点的简单方法是使用与变量名相同的名称,因为在同一范围内不能有两个同名的变量

    您可以在上面看到,我正在分别构建模式的每个部分,但在构建过程中,我将前一个替换项作为第四个参数传递给当前替换项。这将构建替换项链。构建完成后,我将使用最后一个构建的替换项来生成整个模式和求值器。如果您使用除以外的任何项,那么您只会最后,只需将生成的模式和求值器传递给
    Replace
    方法

    请记住,这种方法更多地针对所描述的问题。它可能适用于更一般的场景,但我只使用了您介绍的内容。此外,由于这更像是一个解析问题,解析器可能是正确的选择——尽管学习曲线会更高


    还请记住,我没有分析过这段代码。它当然不会在目标字符串上循环多次,但在替换过程中确实涉及到额外的方法调用。您肯定希望在您的环境中对其进行测试。

    我认为这是一个独特的问题。您可以构建一个类,用于构造e一块一块的整体模式。此类将负责生成
    MatchEvaluator
    委托,该委托也将传递给
    Replace

    class RegexReplacer
    {
        public string Pattern { get; private set; }
        public string Replacement { get; private set; }
        public string GroupName { get; private set; }
        public RegexReplacer NextReplacer { get; private set; }
    
        public RegexReplacer(string pattern, string replacement, string groupName, RegexReplacer nextReplacer = null)
        {
            this.Pattern = pattern;
            this.Replacement = replacement;
            this.GroupName = groupName;
            this.NextReplacer = nextReplacer;
        }
    
        public string GetAggregatedPattern()
        {
            string constructedPattern = this.Pattern;
            string alternation = (this.NextReplacer == null ? string.Empty : "|" + this.NextReplacer.GetAggregatedPattern());   // If there isn't another replacer, then we won't have an alternation; otherwise, we build an alternation between this pattern and the next replacer's "full" pattern
    
            constructedPattern = string.Format("(?<{0}>{1}){2}", this.GroupName, this.Pattern, alternation);    // The (?<XXX>) syntax builds a named capture group. This is used by our GetReplacementDelegate metho.
    
            return constructedPattern;
        }
    
        public MatchEvaluator GetReplaceDelegate()
        {
            return (match) =>
            {
                if (match.Groups[this.GroupName] != null && match.Groups[this.GroupName].Length > 0)    // Did we get a hit on the group name?
                {
                    return this.Replacement;
                }
                else if (this.NextReplacer != null)                                                     // No? Then is there another replacer to inspect?
                {
                    MatchEvaluator next = this.NextReplacer.GetReplaceDelegate();
    
                    return next(match);
                }
                else
                {
                    return match.Value;                                                                 // No? Then simply return the value
                }
            };
        }
    }
    
    因为您希望每个替换程序都知道它是否成功,并且因为我们正在通过使用组名对此进行攻击,所以您希望确保每个组名都是不同的。确保这一点的简单方法是使用与变量名相同的名称,因为在同一范围内不能有两个同名的变量

    您可以在上面看到,我正在分别构建模式的每个部分,但在构建过程中,我将前一个替换项作为第四个参数传递给当前替换项。这将构建替换项链。构建完成后,我将使用最后一个构建的替换项来生成整个模式和求值器。如果您使用除以外的任何项,那么您只会最后,只需将生成的模式和求值器传递给
    Replace
    方法

    请记住,这种方法更多地针对所描述的问题。它可能适用于更一般的场景,但我只使用了您介绍的内容。此外,由于这更像是一个解析问题,解析器可能是正确的选择——尽管学习曲线会更高


    还请记住,我没有分析过这段代码。它当然不会在目标字符串上循环多次,但在替换过程中会涉及额外的方法调用。您肯定希望在您的环境中测试它。

    this
    .Replace(@“\%”,@“%”)
    %
    替换为
    %
    ,为了将
    \%
    替换为
    %
    ,您的模式必须是
    。如果您不知道,这是一个以@开头的逐字字符串,它被读取为文字字符,转义序列不被解析,例如:“\\”不被解析为“\,并保留为“\\”。您的示例显示结果为“\\%”->“\%”,而不是“%”。我觉得奇怪,你刚才只指出了这一部分,因为还有更多。你考虑过使用像ANTLR这样的完整解析器吗?嗯,我尝试过寻找解析文本命令的最佳方式。但不幸的是,我不知道这些解析器是否能像我这样做:“[TextBox,[Options]”。这些[Options]有很多参数(大约30+或更多),它们可以作为默认值和自由排列保留。例如:“TextBox,Name=Qufad,Clear,ShowName,Draw,Draw,Draw,Draw,Draw,Draw,Show”。示例2:“TextBox,BorderLeft=两次,BorderRight=两次,BorderTop=一半,BorderBottom=自动”。虽然我必须实现一个大的switch case语句来正确解析所有内容。所有这些命令都调用method或modify字段。此
    .Replace(@“\%”,@“%”)将
    %
    替换为
    %
    ,为了将
    \%
    替换为
    %
    ,您的模式必须是
    。Replace(@“\%”,@“\%”)
    如果您不知道,这是一个以@开头的逐字字符串,它被读取为文字字符,转义序列没有被解析,例如:“\\”没有被解析为“\”,它仍然是“\\”。您的示例显示结果是“\\\%”->“\%”,而不是“%”。我觉得奇怪,你刚才只指出了这一部分,因为还有更多。你考虑过使用像ANTLR这样的完整解析器吗?嗯,我尝试过寻找解析文本命令的最佳方式。但不幸的是,我不知道这些解析器是否能像我这样做:“[TextBox,[Options]”。这些[Options]有很多参数(大约30+或更多),它们可以作为默认值和自由排列被忽略。例如:“TextBox,Name=Qufad,Clear,ShowName,Draw,Draw,Druck,Show”。示例2:“TextBox,BorderLeft=Twic
    string target = @"$global name$ Money \$9000 %local var% It's over 9000\% I@hit@the@ground@too@hard qw\@op";
    RegexReplacer dollarWrapped = new RegexReplacer(@"(?<!\\)\$[^$]+\$", "motherofglobalvar", "dollarWrapped");
    RegexReplacer slashDollar = new RegexReplacer(@"\\\$", string.Empty, "slashDollar", dollarWrapped);
    RegexReplacer percentWrapped = new RegexReplacer(@"(?<!\\)%[^%]+%", "lordoflocalvar", "percentWrapped", slashDollar);
    RegexReplacer slashPercent = new RegexReplacer(@"\\%", string.Empty, "slashPercent", percentWrapped);
    RegexReplacer singleAt = new RegexReplacer(@"(?<!\\)@", " ", "singleAt", slashPercent);
    RegexReplacer slashAt = new RegexReplacer(@"\\@", "@", "slashAt", singleAt);
    RegexReplacer replacer = slashAt;
    string pattern = replacer.GetAggregatedPattern();
    MatchEvaluator evaluator = replacer.GetReplaceDelegate();
    string result = Regex.Replace(target, pattern, evaluator);