首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c#:如何区分字符串的两个变体

c#:如何区分字符串的两个变体
EN

Stack Overflow用户
提问于 2011-05-12 21:24:51
回答 2查看 561关注 0票数 0

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

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

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

都翻译成第一季第五集

但是,如果用户向后输入E05S01或0501,我需要返回相同的结果,第一季第5集。

这方面的控件是用户定义原始文件名的格式,其内容如下:"SssEee“--大写”S“,表示以下小写'S‘'s’属于季节,大写'E‘表示下面的小写'e’属于Episode。因此,如果用户决定将格式定义为EeeSss,那么我的函数仍然应该返回相同的结果,因为它知道哪些数字属于季节或插集。

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

代码语言:javascript
复制
public static int(string userFormat, string fileName)
{

}

userFormat将是一个字符串,其外观如下所示:

t.SssEee

甚至是

t.SssEee

标题在哪里,其余的你都知道。

文件名可能如下所示:

freesstar.galactica.S01E05.mkv

通过使用userFormat构建regex字符串,我获得了从文件名中提取标题的函数。

代码语言:javascript
复制
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);
        }

但我对如何提取剧集和季数感到困惑。在我的脑海里,我认为这个过程看起来像是:

pattern

  • Extract
  • 查看userFormat字符串,以查找大写S
  • ,确定大写S
  • 后面有多少小写字母,构建了通过文件名描述
  • 搜索的regex表达式,并找到来自该模式的数字

F 219

听起来很简单,但我很难把它付诸行动。复杂的是,文件名中的格式可以是S01E05,也可以是0105。当用户定义格式时,这两种场景都将由用户标识。

Ex 1.文件名为battlestar.galactica.S01E05

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

文件名为.galactica.0105

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

文件名为.galactica.0501

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

对不起这本书..。这个概念很简单,regex函数应该是动态的,允许用户将文件名的格式定义到我的方法可以生成表达式并使用它从文件名中提取信息的地方。有东西告诉我这比看上去简单..。但我不知所措。哈哈..。有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2011-05-12 21:49:48

所以,如果我读对了,你知道季节/史诗数字在字符串中的位置,因为用户已经告诉你了。也就是说,你有t.t.<number>.more.stuff<number>可以采取以下几种形式之一:

代码语言:javascript
复制
SssEee
EeeSss
ssee
eess

或者你说用户可以定义在季和集中将使用多少位数?也就是说,会是S01E123吗?

我不确定你是否需要一个判决。因为您知道这个格式,而且看起来事情是由句点分隔的(我假设在各个字段中不可能有句点),所以您应该能够使用String.Split提取片段,并且从用户的格式中知道产生的数组中有季节/Episode。所以,现在有一个字符串,它采用上面的形式之一。

您有用户的格式定义和季节/史诗编号。您应该能够编写一个循环,将两个字符串放在一起,并提取必要的信息,或者发出错误。

代码语言:javascript
复制
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;
    }
}

请注意,您可能需要做一些检查,以确保长度是正确的。也就是说,当用户的格式是S01E1时,上面的代码将接受SssEee。您可以添加更多的错误处理,这取决于您对输入错误的担忧程度。但我认为这给了你这个想法的要旨。

我必须认为,这将比尝试动态构建正则表达式容易得多。

票数 1
EN

Stack Overflow用户

发布于 2011-05-13 14:14:01

在回答了我的问题后,我们可以将他最初的帖子缩减为:挑战是接收这些输入:

SxxEyy)

  • S01E05

  • E05S01 OR

  • 1x05
  1. 0105 (如果您的输入为0105,则假定为

(第一季第5集)。

并将任何这些输入转换为: S01E05

在这一点上,标题和文件格式是不相关的,他们只是被加到最后。

基于此,以下代码将始终生成“Battlestar.Galactica.S01E05.mkv”

代码语言:javascript
复制
  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;

  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5984658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档