c#:正则表达式如何区分字符串的两种变体

c#:正则表达式如何区分字符串的两种变体,c#,regex,string,dynamic,builder,C#,Regex,String,Dynamic,Builder,这个问题很难解释,但我会尝试: 我有两种用户输入的可能性: S01E05或0105(两个不同的输入字符串) 这两个版本都翻译成了第1季第5集 但是如果他们用户向后输入E05S01或0501,我需要能够返回相同的结果,第1季第5集 此控件将由用户定义原始文件名的格式,如下所示: “SssEee”--大写字母“S”表示以下小写字母“S”属于季节,大写字母“E”表示以下小写字母“E”属于情节。因此,如果用户决定将格式定义为EeeSss,那么我的函数仍然应该返回相同的结果,因为它知道哪些数字属于季节或插

这个问题很难解释,但我会尝试:

我有两种用户输入的可能性:

S01E05或0105(两个不同的输入字符串)

这两个版本都翻译成了第1季第5集

但是如果他们用户向后输入E05S01或0501,我需要能够返回相同的结果,第1季第5集

此控件将由用户定义原始文件名的格式,如下所示: “SssEee”--大写字母“S”表示以下小写字母“S”属于季节,大写字母“E”表示以下小写字母“E”属于情节。因此,如果用户决定将格式定义为EeeSss,那么我的函数仍然应该返回相同的结果,因为它知道哪些数字属于季节或插曲

我还没有什么东西可以共享,但我所玩的是一个构建regex模式的循环。到目前为止,该函数接受用户格式和文件名:

public static int(string userFormat, string fileName)
{

}
userFormat将是一个字符串,如下所示:

t、 t.t.SssEee

甚至

t、 SssEee

其中t代表头衔,其余的你都知道

文件名可能如下所示:

太空堡垒.卡拉狄加.S01E05.mkv

我得到了一个函数,它使用userFormat构建正则表达式字符串,从文件名中提取标题

public static string GetTitle(string userFormat, string fileName)
        {
            string pattern = "^";
            char positionChar;
            string fileTitle;

            for (short i = 0; i < userFormat.Length; i++)
            {
                positionChar = userFormat[i];

                //build the regex pattern
                if (positionChar == 't')
                {
                    pattern += @"\w+";
                }
                else if (positionChar == '#')
                {
                    pattern += @"\d+";
                }
                else if (positionChar == ' ')
                {
                    pattern += @"\s+";
                }
                else
                    pattern += positionChar;
            }

            //pulls out the title with or without the delimiter
            Match title = Regex.Match(fileName, pattern, RegexOptions.IgnoreCase);
            fileTitle = title.Groups[0].Value;

            //remove the delimiter
            string[] tempString = fileTitle.Split(@"\/.-<>".ToCharArray());
            fileTitle = "";
            foreach (string part in tempString)
            {
                fileTitle += part + " ";
            }

            return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(fileTitle);
        }
publicstaticstringgettitle(stringuserformat,stringfilename)
{
字符串模式=“^”;
字符位置字符;
字符串文件名;
for(短i=0;i
但是我有点困惑于如何提取剧集和季号。在我的脑海中,我认为这个过程会是这样的:

  • 查看userFormat字符串以查找大写字母S
  • 确定大写字母后面有多少个小写字母
  • 构建描述此问题的正则表达式
  • 搜索文件名并找到该模式
  • 从该模式中提取数字
听起来很简单,但我很难付诸行动。复杂的是,文件名中的格式可能是S01E05,也可能只是0105。用户在定义格式时,可以识别任何一种情况

ex1。文件名为battlestar.galactica.S01E05

提交的用户格式为t.t.?ss?ee

ex2。文件名为battlestar.galactica.0105

提交的用户格式为t.t.SssEee

ex3。文件名为battlestar.galactica.0501

提交的用户格式为t.t.EESSS


对不起,这本书。。。概念很简单,regex函数应该是动态的,允许用户定义文件名的格式,我的方法可以在其中生成表达式,并使用它从文件名中提取信息。有些事情告诉我,这比看起来更简单。。。但是我不知所措。英雄联盟有什么建议吗?

如果我读对了这篇文章,你就会知道季/集号在字符串中的位置,因为用户已经告诉你了。也就是说,你有
t.t..more.stuff
。而
可以采用以下形式之一:

SssEee
EeeSss
ssee
eess

或者你是说用户可以定义季和集将使用多少个数字?也就是说,可能是S01E123吗

我不确定你需要一个正则表达式。由于您知道格式,而且似乎是由句点分隔的(我假设各个字段中不存在句点),因此您应该能够使用
String.Split
提取片段,并且您可以从用户的格式中知道季节/插曲在结果数组中的位置。现在有了一个字符串,它采用上面的一种形式

您有用户的格式定义和季/集编号。您应该能够编写一个循环,逐步遍历两个字符串并提取必要的信息,或者发出错误

string UserFormat = "SssEee";
string EpisodeNumber = "0105";

int ifmt = 0;
int iepi = 0;
int season = 0;
int episode = 0;

while (ifmt <= UserFormat.Length && iepi < EpisodeNumber.Length)
{
    if ((UserFormat[ifmt] == "S" || UserFormat[ifmt] == "E"))
    {
        if (EpisodeNumber[iepi] == UserFormat[ifmt])
        {
            ++iepi;
        }
        else if (!char.IsDigit(EpisodeNumber[iepi]))
        {
            // Error! Chars didn't match, and it wasn't a digit.
            break;
        }
        ++ifmt;
    }
    else
    {
        char c = EpisodeNumber[iepi];
        if (!char.IsDigit(c))
        {
            // error. Expected digit.
        }
        if (UserFormat[ifmt] == 'e')
        {
            episode = (episode * 10) + (int)c - (int)'0';
        }
        else if (UserFormat[ifmt] == 's')
        {
            season = (season * 10) + (int)c - (int)'0';
        }
        else
        {
            // user format is broken
            break;
        }
        ++iepi;
        ++ifmt;
    }
}
string UserFormat=“SssEee”;
字符串eposodenumber=“0105”;
int-ifmt=0;
int-iepi=0;
int季节=0;
int=0;

而在@sineauthm回答我的问题后,我们可以将他的原始帖子缩减为: 挑战在于接收以下任何输入:

  • 0105(如果您的输入为0105,则假设为SxxEyy)
  • S01E05
  • E05S01
  • 1x05(读作第1季第5集)
  • 并将这些输入转换为:S01E05
    在这一点上,标题和文件格式是不相关的,它们只是被固定在末尾

    基于此,以下代码将始终生成“太空堡垒.卡拉狄加.S01E05.mkv”

      static void Main(string[] args)
      {
         string[] inputs = new string[6] { "E05S01", "S01E05", "0105", "105", "1x05", "1x5" };
         foreach (string input in inputs)
         {
            Console.WriteLine(FormatEpisodeTitle("Battlestar.Galactica", input, "mkv"));
         }
    
    
         Console.ReadLine();
      }
    
    
      private static string FormatEpisodeTitle(string showTitle, string identifier, string fileFormat)
      {
         //first make identifier upper case
         identifier = identifier.ToUpper();
    
         //normalize for SssEee & EeeSee
         if (identifier.IndexOf('S') > identifier.IndexOf('E'))
         {
            identifier = identifier.Substring(identifier.IndexOf('S')) + identifier.Substring(identifier.IndexOf('E'), identifier.IndexOf('S'));
         }
    
         //now get rid of S and replace E with x as needed:
         identifier = identifier.Replace("S", string.Empty).Replace("E", "X");
    
    
         //at this point, if there isn't an "X" we need one, as in 105 or 0105
         if (identifier.IndexOf('X') == -1)
         {
            identifier = identifier.Substring(0, identifier.Length - 2) + "X" + identifier.Substring(identifier.Length - 2);
         }
    
         //now split by the 'X'
         string[] identifiers = identifier.Split('X');
    
         // and put it back together:
         identifier = 'S' + identifiers[0].PadLeft(2, '0') + 'E' + identifiers[1].PadLeft(2, '0');
    
         //tack it all together 
         return showTitle + '.' + identifier + '.' + fileFormat;
    
      }
    

    ssee格式是否模棱两可?0501可能是第5集第1季或第5季第1集…(也不确定这到底是为了什么,但我