代码之家  ›  专栏  ›  技术社区  ›  joshua

regex拼图查找所有有效的字符串组合

  •  0
  • joshua  · 技术社区  · 6 年前

    我试图在满足所有给定条件的字符串中找到可能的子集。

    • 第一个字母是小写英文字母。
    • 接下来,它包含以下零个或多个字符的序列:
      小写英文字母、数字和冒号。
    • 接下来,它包含一个正斜杠“/”。
    • 接下来,它包含以下一个或多个字符的序列:
      小写英文字母和数字。
    • 接下来,它包含一个反斜杠''。
    • 接下来,它包含一个或多个小写英文字母的序列。

    给定一些字符串s,我们定义如下:

    1. s[i..j]是由索引i和索引j之间包含范围内的所有字符组成的子字符串。
    2. 两个子串,s[i 1 J ]和s[i[2]。.j[2]被认为是不同的,如果我 __i[2]或j J〔2〕。

    例如,命令行是 abc:/b1c\xy. 有效的命令子字符串为:

    abc:/b1c\xy
    bc:/b1c\xy
    c:/b1c\xy
    abc:/b1c\x
    bc:/b1c\x
    c:/b1c\x
    

    我解决的问题是 ^([a-z])([a-z0-9:]*)(/)([a-z0-9]+)([\\])([a-z]*)

    但这不满足第二个条件,我试过了 ^([a-z])([a-z0-9:]*)(/)([a-z0-9]+)([\\])([a-z]+[a-z]*) 但仍然是为了 w:/a\bc 应该是2个子集[ w:/a\b,w:/a\bc ]但根据正则表达式,它的1是obviuos。我做错了什么

    Regex工具: Check

    编辑:why w:/a\bc应生成两个子集[ w:/a\b, w:/a\bc ],因为它满足所有6个约束,并且其独特的 W:/A\BC '是超级集 w:/a\b ,

    3 回复  |  直到 6 年前
        1
  •  1
  •   grek40    6 年前

    您可以创建一个regex来帮助您分离所有相关的结果部分,但据我所知,您不能创建一个regex来用一次搜索来提供所有结果集。

    棘手的部分是前两个条件,因为当字母、数字和冒号混合在一起时,可能会有许多起点。

    为了找到可能的起始点,我建议在正斜杠之前的部分采用以下模式: (?:([a-z]+)(?:[a-z0-9:]*?))+

    这将匹配多个捕获,其中捕获中的每个字母都可能是子字符串的起点。

    整个regex: (?:([a-z]+)(?:[a-z0-9:]*?))+/[a-z0-9]+\\([a-z]*)

    通过组合组1的所有捕获的所有后缀子长度和组2的所有前缀子长度来创建结果。

    示例代码:

    var testString = @"a:ab2c:/b1c\xy";
    
    var reg = new Regex(@"(?:([a-z]+)(?:[a-z0-9:]*?))+/[a-z0-9]+\\([a-z]*)");
    
    var matches = reg.Matches(testString);
    
    foreach (Match match in matches)
    {
        var prefixGroup = match.Groups[1];
        var postfixGroup = match.Groups[2];
    
        foreach (Capture prefixCapture in prefixGroup.Captures)
        {
            for (int i = 0; i < prefixCapture.Length; i++)
            {
                for (int j = 0; j < postfixGroup.Length; j++)
                {
                    var start = prefixCapture.Index + i;
                    var end = postfixGroup.Index + postfixGroup.Length - j;
                    Console.WriteLine(testString.Substring(start, end - start));
                }
            }
        }
    }
    

    输出:

    a:ab2c:/b1c\xy
    a:ab2c:/b1c\x
    ab2c:/b1c\xy
    ab2c:/b1c\x
    b2c:/b1c\xy
    b2c:/b1c\x
    c:/b1c\xy
    c:/b1c\x
    
        2
  •  3
  •   Owais Ch    6 年前

    匹配字符串后必须执行子字符串操作。

    例如: 您的字符串是“abc:/b1c\xy”,您使用regex匹配它,现在是获取所需数据的时候了。

    int startIndex=1;
    String st="abc:/b1c\xy";
    regex1="[a-z0-9:]*(/)"
    regex2="(/)([a-z0-9]+)([\\])";
    regex3="([\\])([a-z])+";
    String PrefixedString=regex1.match(st).group(0);
    String CenterString=regex2.match(st).group(0);
    String PostfixedString=regex3.match(st).group(0);
    if(PrefixedString.contains(":"))
    {  startIndex=2; }
    for(int i=;i<PrefixedString.length-startIndex;i++)//ends with -startIndex because '/' is included in the string or ':' may be
    {
        String temp=PrefixedString[i];
        if(i!=PrefixedString.length)
        {
            for(int j=i+1;j<PrefixedString.length;j++)
            {
                 temp+=PrefixedString[j];
            }
        }
        print(temp+CenterString+PostfixedString);
    }
    for(int i=1;i<PostfixedString.length;i++)//starts with -1 because '\' is included in the string
    {
        String temp=PrefixedString+CenterString+PostfixedString[i];
        if(i!=PostfixedString.length)
        {
            for(int j=i+1;j<PostfixedString.length;j++)
            {
                 temp+=PostfixedString[j];
            }
        }
        print(temp);
    }
    

    我希望这能给你一些建议。

        3
  •  0
  •   joshua    6 年前

    直观的方法可能不正确。

    var regex = new Regex(@"(^[a-z])([a-z0-9:]*)(/)([a-z0-9]+)([\\])([a-z]+)");
            var counter = 0;
            for (var c = 0; c < command.Length; c++)
            {
                var isMatched = regex.Match(string.Join(string.Empty, command.Skip(c)));
                if (isMatched.Success)
                {
                    counter += isMatched.Groups.Last().Value.ToCharArray().Length;
                }
            }
            return counter;