【问题标题】:Grouping string using Regular Expression使用正则表达式对字符串进行分组
【发布时间】:2025-12-19 04:00:10
【问题描述】:

我有下面的字符串

validates="required positiveInteger" label="Enter the Total Value." name="totalvalue" visibleif="hasvalue:Yes"

所以字符串有 4 个属性 validates,label,namevisibleif 具有各自的值

我正在使用dotliquid's regular expression utility class 对属性进行分组。在initialize方法中markup参数下面的值就是上面的字符串。

public class TextBox : DotLiquid.Tag
{
    //R.B and R.Q are dotliquid's utility method
    private static readonly Regex Syntax = R.B(R.Q(@"(?<validation>{0}+)(\s(?<label>{0}+))?(\s(?<name>{0}+))?(\s(?<onlyif>{0}+))?"), Liquid.QuotedFragment);

    private string[] _validations;
    private string[] _label;
    private string[] _name;
    private string[] _onlyif;

    public override void Initialize(string tagName, string markup, List<string> tokens)
    {
        var syntaxMatch = Syntax.Match(markup);
        if (syntaxMatch.Success)
        {
            _validations = syntaxMatch.Groups["validation"].Value.Split("=").TrimQuotes().ToArray();
            _label = syntaxMatch.Groups["label"].Value.Split("=").TrimQuotes().ToArray();
            _name = syntaxMatch.Groups["name"].Value.Split("=").TrimQuotes().ToArray();
            _onlyif = syntaxMatch.Groups["onlyif"].Value.Split("=").TrimQuotes().ToArray();
        }
        else
        {
            throw new SyntaxException("Invalid syntax");
        }

        base.Initialize(tagName, markup, tokens);
    }

    public override void Render(Context context, TextWriter result)
    {
        base.Render(context, result);
    }
}

代码仅适用于给定的字符串,但是存在问题:
1>如果属性的顺序不同,那么分组会被分配错误的值。

2>namelabel 属性是必需的,但 validatesvisibleif 属性不是必需的。 RegEx 应该对此进行验证。

3>如果标记有任何其他额外属性,RegEx 必须失败。

有人可以帮助正确的正则表达式吗?

【问题讨论】:

    标签: c# .net regex dotliquid


    【解决方案1】:

    我怀疑这是否是我们想要解决的问题。但是,在我看来,我们想要捕获属性值。如果是这种情况,我们可能希望从一个简单的表达式开始,然后根据需要进行修改和更改。例如,我们可以使用:

    (validates|label|name|visibleif)=("(.+?)")\s?
    

    如果我们希望使其他字符串失败,那可能很简单,但是我不太确定其他可能的和期望的字符串以提出任何建议。

    正则表达式

    如果不需要此表达式,可以在 regex101.com 中修改或更改。

    正则表达式电路

    jex.im 可视化正则表达式:

    示例测试

    using System;
    using System.Text.RegularExpressions;
    
    public class Example
    {
        public static void Main()
        {
            string pattern = @"(validates|label|name|visibleif)=(""(.+?)"")\s?";
            string input = @"validates=""required positiveInteger"" label=""Enter the Total Value."" name=""totalvalue"" visibleif=""hasvalue:Yes""
    validates=""required positiveInteger"" label=""Enter the Total Value."" name=""totalvalue"" visibleif=""hasvalue:Yes"" fail_attribute=""Undesired""";
            RegexOptions options = RegexOptions.Multiline;
    
            foreach (Match m in Regex.Matches(input, pattern, options))
            {
                Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
            }
        }
    }
    

    演示

    const regex = /(validates|label|name|visibleif)=("(.+?)")\s?/gm;
    const str = `validates="required positiveInteger" label="Enter the Total Value." name="totalvalue" visibleif="hasvalue:Yes"
    validates="required positiveInteger" label="Enter the Total Value." name="totalvalue" visibleif="hasvalue:Yes" fail_attribute="Undesired"`;
    let m;
    
    while ((m = regex.exec(str)) !== null) {
        // This is necessary to avoid infinite loops with zero-width matches
        if (m.index === regex.lastIndex) {
            regex.lastIndex++;
        }
        
        // The result can be accessed through the `m`-variable.
        m.forEach((match, groupIndex) => {
            console.log(`Found match, group ${groupIndex}: ${match}`);
        });
    }

    DEMO

    【讨论】:

    • 如果我按照您的代码建议循环,它会起作用。但是,如果我 groupSyntax.Match(markup) 那么它不会返回正确的组
    【解决方案2】:

    如果我正确理解您的问题,对我来说,您似乎试图通过正则表达式实现太多目标。

    我的假设是,当您在= 上拆分字符串时,您会得到一个键和一个值。关键是属性名,此时可以验证是否提供了labelvalue,无非就是labelvaluevalidatevisibleif

    这样正则表达式需要更简单 - 你只需要在空格上进行拆分,所以也许你根本不需要正则表达式?

    【讨论】:

      最近更新 更多