31

おそらくこれを少し分析しすぎていますが、stackoverflowがどのように示唆するかは、文字列の最後に含まれる整数を返すための最良の方法です。

これまで、単純なループ、LINQ、および正規表現の使用を検討してきましたが、コミュニティからどのようなアプローチが得られるのか興味があります。明らかに、これは解決するのが難しい問題ではありませんが、ソリューションに多くの変動がある可能性があります。

具体的には、任意の長さの文字列の最後に追加される任意の長さの整数/長さを返す関数をどのように作成しますか?

CPR123 => 123
ABCDEF123456 => 123456
4

9 に答える 9

49

この正規表現を使用します。

\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());
于 2012-11-01T00:35:53.827 に答える
26

必須のLINQワンライナー

var input = "ABCD1234";
var result = string.Concat(input.ToArray().Reverse().TakeWhile(char.IsNumber).Reverse());
于 2017-06-02T13:44:07.933 に答える
11

\d+$デフォルトでは、文字列は左から右に解析されるため、のような正規表現パターンは少し高価です。正規表現エンジンがで検出1される12abc34と、一致し続け、が検出される2a、一致は失敗し、次の位置が試行されます。

ただし、.NET正規表現にはRegexOptions.RightToLeft修飾子があります。これにより、正規表現エンジンが文字列を右から左に解析し、最後に近いことがわかっている一致をはるかに速く取得できる場合があります。

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

オンラインのC#デモを参照してください。

于 2017-10-17T23:26:33.377 に答える
4

私の経験では、正規表現が最も簡単です。

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

これはそれに一致するはずです。それを関数でラップするだけです。

于 2012-11-01T00:37:38.083 に答える
1
[^0-9]+([0-9]+)

やるべきだと思う

于 2012-11-01T00:35:57.447 に答える
1

それは常にLettersNumbersの形式ですか?

その場合、これは機能します。

Regex _cellAddressRegex = new Regex(@"(?<Column>[a-z]+)(?<Row>[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
var rowm = Convert.ToInt32(parts.Groups["Row"]);
于 2012-11-01T00:36:43.980 に答える
0

これに夢中になることは許されますか?

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());
}
于 2012-11-01T01:31:08.750 に答える
0

単純なループは、その単純さと効率において、おそらく他のどのソリューションよりも優れているはずです。そして、最終的に返される文字列は、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);
}
于 2018-04-11T12:08:54.340 に答える
0

理解しにくい正規表現や、低速になる可能性のあるLinqと配列操作を使用せずに、拡張メソッドの単純なループを使用できます。

とチェックを適応させながら、longまたはintまたはulongまたはまたはその他に使用できます。uint+-

解析するように適合させることもfloatできdoubleますdecimal

このメソッドは、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
于 2019-11-06T09:01:00.420 に答える