首页 > 解决方案 > C# 使用正则表达式或常规迭代解析字符串

问题描述

我有一个可以采用以下任何格式的字符串,我期待这样的输出:-

if E31f -> E
if E3X -> E3
if E3 -> E3
if M5 -> M
if BR30O -> BR
if BR10E -> BR
if BRC -> BR
if BR3 -> BR3
if BR3R -> BR3
if WT2O -> WT
if WT3E -> WT3
if T1A -> T
if T3O -> T3
if TO2 -> TO
if TO3E -> TO3
if EL6 -> EL
if EL3 -> EL3
if E -> E
if T3 -> T3
if BC1 -> BC
if BC3 -> BC3

我想知道输入字符串是否为E3E/E3F/E3O,那么输出应该是 -> 'E3'only。

否则,如果输入字符串是E31F,那么输出应该是 -> 'E'only。

开头字母“E”只是一个示例……它可以是 BR3、WT3、T3、TO3、EL3、BC3。它可能包含也可能不包含数字“3”。

我试图找出在数值存在的前几个字符之后......数字3是否单独存在,如果是,则提取字符和数字3(E3,BR3等)。

但是,如果在前几个字符之后,数字 3 存在附加其他数字,则只提取字符串中数字前的字符(E、BR 等)。

我试图弄清楚这样做的最佳方法是什么。是使用正则表达式还是我应该使用使用 for 循环的常规方式来遍历字符串。

标签: c#regexstring

解决方案


这是OP编辑问题后答案的编辑版本。

正则表达式

.+ ==> 取 1 个或多个字符。

3 ==> 3 必须存在。

[A-Za-z0-9] ==> 立即获取 3 之后的字符/数字。

.* ==> 零个或多个字符结束字符串。

var regex = new Regex(@"(.+)3([A-Za-z0-9]).*");

在这里,Groups[2]包含紧跟在 之后的值3Groups[1]包含前导到 的字符3

因此,通过使用int.TryParse(),如果紧随其后的值3是一个数字,我们只能得到前面的字符3。否则(即后面的字符3不是数字),那么我们得到前面的字符+2。

var list = new List<string>() { "E31F", "E3X", "BR39FG", "BR3X" };

foreach (var word in list)
{
    var match = regex.Match(word);
    if (match.Success)
    {
        var after3 = match.Groups[2].Value;
        string result = string.Empty;
        if (int.TryParse(after3, out int res))
        {
            result = match.Groups[1].Value;
        }
        else
        {
            result = match.Groups[1].Value + "3";
        }
        Console.WriteLine("{0} ==> {1}", word, result);
    }
}

输出

E31F ==> E

E3X ==> E3

BR39FG ==> BR

BR3X ==> BR3

EDIT2(在OP发布澄清后)

所以更新的条件:

E、M、BR、WT、T、TO、EL、BC 是我正在寻找的主要字符串。然后我想看看它后面是否只有数字 3。如果是,那么我想要附加字符前缀和数字。如果没有,那么只有字符前缀。

在这种情况下,我会放弃这种Regex方法。这是一个带有解释的代码。

static void Main()
{
    var words = new List<string>() { "E31f", "E3X", "E3", "M5", "BR30O", "BR10E", "BRC", "BR3", "BR3R", "WT2O", "WT3E", "T1A", "T3O", "TO2", "TO3E", "EL6", "EL3", "E", "T3", "BC1", "BC3" };
    var keywords = new List<string>() { "E", "M", "BR", "WT", "T", "TO", "EL", "BC" };

    // We need to be a little tactful here. Your keyword list contains both E and EL, so if we simply do a `string.Contains()`, we want to make sure that EL is considered before E.
    // So we sort by length first, and then by ascending order.
    // So the sorted keywords look like this: BC,BR,EL,TO,WT,E,M,T
    var sortedKeywords = keywords.OrderByDescending(x => x.Length).ThenBy(x => x);

    foreach (var word in words)
    {
        var extract = string.Empty;

        // We see if the selected word in the list starts with any of the keys in the sorted list.
        // Since we started it, EL will be checked before E, TO will be checked before T, etc.
        var key = sortedKeywords.FirstOrDefault(word.StartsWith);
        if (!string.IsNullOrEmpty(key))
        {
            extract = key;
            // We set the extract = key. Now if key is the same as the word, we simply contiue the loop.
            if (word.Length > key.Length)
            {
                // If there are more characters we check the next character.
                var next = word.Skip(key.Length).Take(1).FirstOrDefault().ToString();
                if (int.TryParse(next, out int num))
                {
                    if (num == 3)
                    {
                        // If the next character is 3 and there are more characters
                        if (word.Length > key.Length + 1)
                        {
                            // Check the next of next
                            var nextnext = word.Skip(key.Length + 1).Take(1).FirstOrDefault().ToString();
                            // If next of next is not a number, we append 3 to the ky
                            // Otherwise extract is the same as the key which we already set
                            if (!int.TryParse(nextnext, out num))
                            {
                                extract = key + 3.ToString();
                            }
                        }
                        // If the next character is 3 and its the last one, we append 3 to the key
                        else
                        {
                            extract = key + 3.ToString();
                        }
                    }
                }
            }
        }
        Console.WriteLine("{0} --> \t{1}", word, extract);
    }

    Console.ReadLine();
}

输出

E31f --> E

E3X --> E3

E3 --> E3

M5 --> M

BR30O --> BR

BR10E --> BR

BRC --> BR

BR3 --> BR3

BR3R --> BR3

WT2O --> WT

WT3E --> WT3

T1A --> T

T3O --> T3

TO2 --> 到

TO3E --> TO3

EL6 --> EL

EL3 --> EL3

E --> E

T3 --> T3

BC1 --> BC

BC3 --> BC3


推荐阅读