繁体   English   中英

正则表达式使用C#保持未知长度的字符串的最后4个字符

[英]Regex to keep the last 4 characters of a string of unknown length using C#

我需要使用正则表达式来保留字符串的最后4个字符。 我不知道字符串的长度所以我需要从最后开始并向后计数。 该程序是用c#编写的。

以下是两个示例字符串:

  • 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;
        }

非常感谢,感谢您的帮助。

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因为没有. 在正则表达式。

.*(?=.{4})$

将匹配字符串的最后四个字符。 如果将该匹配替换为String.Empty ,则仅保留这四个字符。

如果字符串包含少于四个字符,它们将保留在字符串中,因为正则表达式根本不匹配,因此无需替换。

您不需要为此目的使用正则表达式。

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

那部分((MyString.Length >= 4) ? (4) : (0))用于检查原始字符串是否长于或等于4个字符,然后它将返回持续4个字符,否则整个字符串

如果这必须是正则表达式,我想你想要: .{4}(?=\\s|$)

但我同意正则表达式可能不是最好的解决方案。

细分:

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

我想这与你的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;
}

我会使用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

您可以尝试使用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样本

我会尽可能使用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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM