正则表达式拼图查找所有有效的字符串组合

时间:2018-07-17 12:12:32

标签: c# regex

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

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

给出一些字符串s,我们定义以下内容:

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

正则表达式工具:1

编辑:为什么w:/ a \ bc应该产生两个子集[w:/a\b, w:/a\bc],使其满足所有6个约束,并且其区别在于“ w:/a\bc”是w:/a\b的超集,

3 个答案:

答案 0 :(得分:3)

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

例如: 您的字符串是“ 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);
}

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

答案 1 :(得分:1)

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

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

为了找到可能的起点,我建议在正斜杠之前的部分使用以下模式:(?:([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

答案 2 :(得分:0)

直观方式可能不正确。

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;