簡體   English   中英

在 C# 中提取字符串末尾的數字

[英]Extract number at end of string in C#

可能會稍微分析一下,但是 stackoverflow 建議如何返回包含在字符串末尾的整數的最佳方法。

到目前為止,我已經考慮使用一個簡單的循環、LINQ 和正則表達式,但我很好奇我會從社區獲得什么方法。 顯然,這不是一個很難解決的問題,但在解決方案中可能會有很多差異。

因此,更具體地說,您將如何創建一個函數來返回附加在任意長字符串末尾的任意長整數/long?

CPR123 => 123
ABCDEF123456 => 123456

使用這個正則表達式:

\d+$

var result = Regex.Match(input, @"\d+$").Value;

或使用Stack ,可能更有效:

var stack = new Stack<char>();

for (var i = input.Length - 1; i >= 0; i--)
{
    if (!char.IsNumber(input[i]))
    {
        break;
    }

    stack.Push(input[i]);
}

var result = new string(stack.ToArray());

強制性 LINQ 單行

var input = "ABCD1234";
var result = string.Concat(input.ToArray().Reverse().TakeWhile(char.IsNumber).Reverse());

\\d+$正則表達式有點昂貴,因為默認情況下,字符串是從左到右解析的。 一旦正則表達式引擎在12abc34找到1 ,它就會繼續匹配2 ,當遇到a ,匹配失敗,嘗試下一個位置,依此類推。

但是,在 .NET 正則表達式中,有一個RegexOptions.RightToLeft修飾符。 它使正則表達式引擎從右到左解析字符串,您可能會更快地獲得已知更接近結尾的匹配項。

var result = Regex.Match("000AB22CD1234", @"\d+$", RegexOptions.RightToLeft);
if (result.Success) 
{ 
    Console.Write(result.Value);
}  // => 1234

請參閱在線 C# 演示

就我的經驗而言,正則表達式將是最簡單的。

Regex ex = new Regex(@"(\d+)$")

這應該匹配它。 只需將其包裝在一個函數中即可。

[^0-9]+([0-9]+)

我認為應該這樣做

它總是采用 LettersNumbers 格式嗎?

在這種情況下,這將起作用:

Regex _cellAddressRegex = new Regex(@"(?<Column>[a-z]+)(?<Row>[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var rowm = Convert.ToInt32(parts.Groups["Row"]);

我可以為此發瘋嗎?

using System.Text;
using System.Linq;

static string GetNum(string input)
{
    StringBuilder sb = new StringBuilder();
    for (int i = input.Length - 1; i >= 0; i--)
    {
        if (input[i] < 48 || input[i] > 57)
            break;

        sb.Append(input[i]);
    }

    return String.Concat(sb.ToString().ToCharArray().Reverse());
}

一個簡單的循環應該在其簡單性和效率方面擊敗任何其他解決方案。 並且最終返回的字符串可以只復制一次,無需使用 Stack、StringBuilder、string.Concat 或其他更復雜的字符串支持函數。

string GetNumberFromEnd(string text)
{
    int i = text.Length - 1;
    while (i >= 0)
    {
        if (!char.IsNumber(text[i])) break;
        i--;
    }
    return text.Substring(i + 1);
}

或者它甚至可以直接作為 int 類型返回:

bool GetIntFromEnd(string text, out int number)
{
    int i = text.Length - 1;
    while (i >= 0)
    {
        if (!char.IsNumber(text[i])) break;
        i--;
    }
    return int.TryParse(text.Substring(i + 1), out number);
}

您可以通過使用long或int或ulong或uint或其他方法,並刪除+/-檢查(如果不需要)來使用此擴展方法。

也可以通過選中'.'來分析浮點數,雙精度或十進制'.' ','System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator (必須為一個)。

也可以將此方法編寫為Parse以具有異常。

static public void StringHelperTest()
{
  static public bool TryParseNumberAtEndAsLong(this string str, out long result)
  {
    result = 0;
    if ( string.IsNullOrEmpty(str) )
      return false;
    int index = str.Length - 1;
    for ( ; index >= 0; index-- )
    {
      char c = str[index];
      if ( !char.IsDigit(c) && c != '+' && c != '-' )
      {
        index++;
        break;
      }
    }
    if ( index <= 0 )
      return long.TryParse(str, out result);
    else
      return long.TryParse(str.Substring(index), out result);    }
  }
}

測試:

Action<string> test = str =>
{
  if ( str.TryParseNumberAtEndAsLong(out var value) )
    Console.WriteLine($"\"{str}\" => {value}");
  else
    Console.WriteLine($"\"{str}\" => not a long at the end");
};

test(null);
test("");
test("test");
test("123");
test("-123");
test("test123");
test("test 123");
test("test +123");
test("test -123");
test("test 11111111111111111111");

輸出:

"" => not a long at the end

"" => not a long at the end

"test" => not a long at the end

"123" => 123

"-123" => -123

"test123" => 123

"test 123" => 123

"test +123" => 123

"test -123" => -123

"test 11111111111111111111" => not a long at the end

如果不使用難以理解的 RegEx,或者可能很慢的 Linq 和數組操作,則可以使用擴展方法中的簡單循環。

在調整+-檢查時,它可以用於longintulonguint或其他。

它也可以適用於解析floatdouble float decimaldecimal

這個方法也可以寫成Parse來處理異常。

執行

static public class StringHelper
{
  static public bool TryParseEndAsLong(this string str, out long result)
  {
    result = 0;
    if ( string.IsNullOrEmpty(str) )
      return false;
    int index = str.Length - 1;
    for ( ; index >= 0; index-- )
    {
      char c = str[index];
      bool stop = c == '+' || c == '-';
      if ( !stop && !char.IsDigit(c) )
      {
        index++;
        break;
      }
      if ( stop )
        break;
    }
    return index <= 0 ? long.TryParse(str, out result)
                      : long.TryParse(str.Substring(index), out result);
  }
} 

測試

test(null);
test("");
test("Test");
test("100");
test("-100");
test("100-200");
test("100 - 200");
test("Test 100");
test("Test100");
test("Test+100");
test("Test-100");
test("11111111111111111111");

Action<string> test = str =>
{
  if ( str.TryParseEndAsLong(out var value) )
    Console.WriteLine($"\"{str}\" => {value}");
  else
    Console.WriteLine($"\"{str}\" has not a long at the end");
};

輸出

"" has not a long at the end
"" has not a long at the end
"Test" has not a long at the end
"100" => 100
"-100" => -100
"100-200" => -200
"100 - 200" => 200
"Test 100" => 100
"Test100" => 100
"Test+100" => 100
"Test-100" => -100
"11111111111111111111" has not a long at the end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM