【问题标题】:Regex Puzzle Find all Valid String Combinations正则表达式拼图查找所有有效的字符串组合
【发布时间】:2018-07-17 12:12:31
【问题描述】:

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

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

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

  1. s[i..j] 是一个子字符串,由索引 i 和索引 j 之间的包含范围内的所有字符组成。
  2. 如果 i1 ≠ i[2],则称两个子字符串 s[i1..j1] 和 s[i[2]..j[2]] 是不同的或 j1 ≠ 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 。我做错了什么

正则表达式工具:Check

编辑:为什么 w:/a\bc 应该产生两个子集 [w:/a\b, w:/a\bc],因为它满足所有 6 个约束,并且它的不同之处在于 'w:/a\bc' 是 w:/a\b 的超集,

【问题讨论】:

  • 您认为您可能会从字符串中的同一位置开始获得两个匹配项的想法是错误的。
  • @MaciejLos ,正确的请参见示例 1 和 4。
  • 如果我理解这些条件的含义,我可以提供帮助。为什么w:/a\bc 会产生['w:/a\b','w:/a\bc']?为什么它们不同?
  • @Wiktor 同意你的观点,但这是技巧,区分不同的原因 w:/a\b, w:/a\bc 将是两个不同的集合,而不是一个。
  • 您的第一个条件不满足。我建议测试这个正则表达式模式:^([a-z]){1}([a-z0-9]{0,}:/)([a-z0-9]{1,})([\\])([a-z]{1,}) BTW:我建议下载并安装Expresso,这在创建和测试正则表达式模式的过程中非常方便。

标签: c# regex


【解决方案1】:

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

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

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);
}

我希望这会给你一些想法。

【讨论】:

    【解决方案2】:

    您也许可以创建一个正则表达式来帮助您分离所有相关的结果部分,但据我所知,您无法创建一个通过单个搜索为您提供所有结果集的正则表达式。

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

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

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

    整个正则表达式:(?:([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
    

    【讨论】:

    • 有趣的方式,
    【解决方案3】:

    直觉方式可能不正确。

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多