Regex, чтобы сохранить последние 4 символа строки неизвестной длины, используя С# - программирование
Подтвердить что ты не робот

Regex, чтобы сохранить последние 4 символа строки неизвестной длины, используя С#

Мне нужно использовать регулярное выражение, чтобы сохранить последние 4 символа строки. Я не знаю длину строки, поэтому мне нужно начинать в конце и рассчитывать назад. Программа написана на С#.

Ниже приведены две строки:

  • 840057
  • 1002945

Мне нужен результат (последние 4 символа):

  • 0057
  • 2945

Моя исходная строка кода использовала Regex.Replace, но я не мог найти регулярное выражение для работы, как вы можете видеть в комментариях ниже.

replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);

Я переключил свой код на использование Regex.Match, а затем регулярное выражение (?s)[0-9]{4}$ отлично работало (см. Ниже):

replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);

Однако использование Regex.Match ломает другие регулярные выражения, которые я использую, например, я использую ^(.).* Для получения первой буквы имени. Это работает при использовании Regex.Replace, но сбой при использовании Regex.Match.

Мой код ниже, обратите внимание на исходную строку, содержащую Regex.Replace, закомментирован.

Почему Regex.Match работает с одним выражением, а Regex.Replace работает с другим?

      /// Replaces a wildcard in a string
        /// </summary>
        /// <param name="str">The string for which to replace the wildcards</param>
        /// <param name="row">The DataRow in which the string exists</param>
        /// <param name="wildcard">The wildcard to replace</param>
        /// <returns>The string with the wildcard replaced</returns>
        private static string ReplaceWildcardInString(string str, DataRow row, Wildcard wildcard)
        {
            // If the string is null or empty, return it as is
            if (string.IsNullOrEmpty(str))
                return str;

            // This will hold the replacement value
            var replacementVal = string.Empty;

            // If the replacement column value is not empty
            if (!row.IsDBNullOrNull(wildcard.ReplaceByColumnName))
            {
                // Convert its value to string
                replacementVal = row[wildcard.ReplaceByColumnName].ToString();

                // Apply wildcard regex if given
                if (!string.IsNullOrEmpty(wildcard.Regex) && wildcard.RegexReplaceBy != null)
                    //replacementVal = Regex.Replace(replacementVal, wildcard.Regex, wildcard.RegexReplaceBy);
                    replacementVal = Regex.Match(replacementVal, wildcard.Regex).Value;
            }

            // Replace all wildcards with the replacement value (case insensitive)
            var wildcardPattern = Regex.Escape(string.Format("%{0}%", wildcard.Name));
            str = Regex.Replace(str, wildcardPattern, replacementVal, RegexOptions.Singleline | RegexOptions.IgnoreCase);

            // Return the new string
            return str;
        }

Многие благодарят, я ценю помощь.

4b9b3361

Ответ 1

Метод Regex.Replace заменяет все неперекрывающиеся подстроки, которые соответствуют шаблону регулярного выражения с указанной заменой.

Метод Regex.Match ищет указанную строку ввода для первого появления регулярного выражения.

Итак, когда у вас есть строка типа 1002945, и вы хотите получить ровно 4 цифры с конца, вы можете использовать

var result = Regex.Replace("1002945", @".*([0-9]{4})$", "$1", RegexOptions.Singleline);

или же

var matchResult = Regex.Match("1002945", @"[0-9]{4}$");
if (matchResult.Success) 
{
    Console.WriteLine(matchResult.Value);
}

При замене вы должны соответствовать всей строке, сопоставлять и записывать только последние четыре символа, которые являются цифрами, и утверждать, что индекс регулярных выражений находится в конце строки ($). Обратите внимание на использование параметра RegexOptions.Singleline . для соответствия символу новой строки, который по умолчанию не соответствует. Строка замены должна быть равна $1, обратной обратной ссылке на первую группу захвата, которая фиксирует цифры.

Когда вы используете Regex.Match("1002945", @"[0-9]{4}$").Value, вы сопоставляете 4 цифры, за которыми следуют либо конец строки, либо символ новой строки, и конец строки (это потому что $ совпадает с этим, если вы не хотите разрешать совпадение перед новой строкой и концом строки, используйте \z manchor). Когда совпадение получено, вы можете проверить, был ли он успешным или неудачным с использованием matchResult.Success, и если было совпадение, получите matchResult.Value. Вам больше не нужно RegexOptions.Singleline так как нет . в регулярном выражении.

Ответ 2

.*(?=.{4})$

будет соответствовать всем до четырех последних символов строки. Если вы замените это соответствие на String.Empty, останутся только те четыре символа.

Если строка содержит меньше четырех символов, они останутся в строке, потому что регулярное выражение не будет совпадать, поэтому заменить ничего не стоит.

Ответ 3

Для этой цели вам не нужно использовать регулярное выражение.

string MyLast4Characters = MyString.Substring(((MyString.Length >= 4) ? (MyString.Length - 4) : (0)));

Эта часть ((MyString.Length >= 4)? (4): (0)) предназначена для проверки, является ли исходная строка длиннее или равна 4 символам, тогда она вернет 4 символа, иначе целая строка

Ответ 4

Если это должно быть регулярное выражение, я думаю, что вы хотите:. .{4}(?=\s|$)

Но я согласен, что регулярное выражение, вероятно, не лучшее решение здесь.

Поломка:

.: any character {4}: exacty four times (?=: followed by \s: white space |: or $: a line ending ): end the followed by section

Ответ 5

Я предполагаю, что это что-то с вашим RegexOptions. В моем примере я использую режим SingleLine ((?s)) и многострочную строку:

static void RegexTest()
{
    string str = "i am long string\r\nwith the number 1002945";
    string pattern = @"(?s)[0-9]{4}$"; // or @"(?s).{4}$"
    string num = Regex.Match(str, pattern).Value;
}

Ответ 6

Я бы использовал метод Regex.Match.
Он соответствует только тому, что вам нужно.

Вы можете использовать его одним из двух способов.

string str = "asdf 12345";
if (str.Length > 4)
{
    // Abbreviated ..
    Console.WriteLine( "{0}", Regex.Match(str, @"(?s).{5}$").Value );

    // Verbose ...
    Regex rx = new Regex(@"(?s).{5}$");
    str = rx.Match(str).Value;
    Console.WriteLine( "{0}", str );
}
else {} // Do something else

Выход

12345
12345

Ответ 7

вы можете попробовать и использовать для этой цели Reverse()

Например:-

string input = "1002945";
string rev = new string(input.Reverse().ToArray());
string res = null;

Match match = Regex.Match(rev, @"\d{4}");
if (match != null && !String.IsNullOrEmpty(match.Value))
{
   res = new string(match.Value.Reverse().ToArray());
}

выход:-

2945

Пример Dot.fiddle

Ответ 8

Я бы использовал Regex.Match как можно больше с соответствующими группами:

string str = "Hello :) 1002945";
string pattern = @"(.).*(\d{4})$";
Match match = Regex.Match(str, pattern);
if (match.Success)
{
    string firstChar = match.Groups[1].Value;
    string lastNumber = match.Groups[2].Value;
    Console.WriteLine("First character : " + firstChar);
    Console.WriteLine("Last number : " + lastNumber);
}

Выход:

First character : H
Last number : 2945