选择此模式中的匹配项

时间:2013-06-06 09:53:58

标签: regex

我正在试图找出一个可以应对以下条件的正则表达式:

基本上,下面的一行是一对变量及其值,用一行文字表示。

  1. 变量名称可以是A-Za-z0-9
  2. 逗号分隔对
  3. 值可以是任何值,包括equals和逗号
  4. Variable1=somevalue1,Variable2=somevalue2,Variable3=some,value2

    我希望以下匹配:

    1. Variable1=somevalue1
    2. Variable2=somevalue2
    3. Variable3=some,value2
    4. 感谢任何帮助,谢谢

4 个答案:

答案 0 :(得分:5)

您的要求不具有确定性,因此您不会得到任何结果,正则表达式也无法满足您的需求。

例如,您的样本可以得到以下结果:

  • 匹配1
    • Variable1 => somevalue1,变量2 = somevalue2,Variable3 =一些,值2
  • MATCH2
    • Variable1 => somevalue1
    • Variable2 => somevalue2,Variable3 =一些,值2
  • MATCH3
    • Variable1 => somevalue1,变量2 = somevalue2
    • Variable3 =>一些,值2

等等。

因此,我建议考虑使用值或其他类型的变量分离。

答案 1 :(得分:1)

有一种方法可以做到,但它不可靠,这取决于变量必须以大写字母开头。如果在值中存在,直接跟随大写字母
,它也会(半)失败 ([A-Z][a-zA-Z0-9]*)\s*=\s*(.*?)(?=,[A-Z]|$)

那么我们在这里有什么?

  • ([A-Z][a-zA-Z0-9]*):对以大写字母开头的字符串进行分组匹配,并匹配字母和数字的零次或多次。
  • \s*=\s*:可选择匹配空格,然后选择等号,然后选择空格。
  • (.*?):分组并匹配所有内容,ungreedy。
  • (?=,[A-Z]|$):积极向前看,检查.*?后面是comma and a capital letter还是end of line

Online demo

  

正则表达式真棒,不是吗?

答案 2 :(得分:1)

我通过反向遍历字符串,从最后一个等于字符串结尾的子字符串作为值,然后对于变量名称,按照我的方式删除,并重复直到处理完所有变量来解决这个问题。

我必须做出一个让步,那就是如果用户想要在他们的变量值中使用等号,他们必须使用特殊值!!等于!!然后我在VariableValue类

中实例化该值时替换它

在此庄园中解析1000行的性能测试耗时0.0019秒。所以很快。

string上的'extract'方法是我编写的一个扩展方法,它输出一个子字符串,并返回原始字符串,并删除匹配的子字符串。

        public List<VariableValue> ExtractVariables(string line)
        {
            var variables = new List<VariableValue>();

            while (line != string.Empty)
            {
                // Get the value 
                var value = string.Empty;
                var lastEquals = line.LastIndexOf('=') + 1;
                line = line.Extract(lastEquals, line.Length - lastEquals, out value);

                // Get the variable
                var variable = string.Empty;
                var lastComma = line.LastIndexOf(',') + 1;
                line = line.Extract(lastComma, line.Length - lastComma - 1, out variable);

                // Add to list of results
                variables.Add(new VariableValue(variable, value));

                // Remove the trailing bits
                line = (line == "=")
                           ? string.Empty
                           : line.Remove(line.LastIndexOf(','), line.Length - line.LastIndexOf(','));
            }

            variables.Reverse();
            return variables;
        }

您如何看待我的解决方案?

答案 3 :(得分:1)

显然,包含分隔符的值存在问题。

但是,只要您的密钥不能包含这些分隔符,就可以合理地处理它们。秘制酱的秘诀是这样的:

/(?:,|^)(?=[^,]+=)/

首先我们声明有一个逗号或字符串的开头,后面没有逗号直到下一个等号。实际上,这会拆分给定键/值对中的 last 逗号。

然后我们只循环结果并在第一个等号上分开。

所以我们最终得到了(显然已经翻译成你选择的语言,我使用过的是PHP,但重要的是逻辑):

<?php

    $str = 'Variable1=somevalue1,Variable2=somevalue2,Variable3=some,value2';

    $result = [];
    foreach (preg_split('/(?:,|^)(?=[^,]+=)/', $str, -1, PREG_SPLIT_NO_EMPTY) as $item) {
        $item = explode('=', $item, 2);
        $result[$item[0]] = isset($item[1]) ? $item[1] : '';
    }

    print_r($result);

产生:

Array
(
    [Variable1] => somevalue1
    [Variable2] => somevalue2
    [Variable3] => some,value2
)

See it working