ค้นหาและแยกตัวเลขจากสตริง


319

ฉันมีความต้องการในการค้นหาและแยกจำนวนที่มีอยู่ในสตริง

ตัวอย่างเช่นจากสตริงเหล่านี้:

string test = "1 test"
string test1 = " 1 test"
string test2 = "test 99"

ฉันจะทำสิ่งนี้ได้อย่างไร


2
อาจเป็นจำนวนลบหรือไม่ ถ้าเป็นเช่นนั้นคุณจะ "สวัสดี - สบายดีแค่ไหน? -30"
Jon Skeet

สวัสดีจอห์นไม่มีตัวเลขติดลบในข้อมูล
van

4
ตัวเลขทศนิยมเป็น1.5อย่างไร สัญลักษณ์เลขชี้กำลังเป็น1.5E45อย่างไร
Tim Pietzcker

ที่คล้ายกัน (แต่ไม่เหมือนกัน): stackoverflow.com/questions/1561273/…
finnw

3
ทำไมไม่มีคำตอบที่นี่?
Wiktor Stribiżew

คำตอบ:


63

ผ่านสตริงและใช้ Char.IsDigit

string a = "str123";
string b = string.Empty;
int val;

for (int i=0; i< a.Length; i++)
{
    if (Char.IsDigit(a[i]))
        b += a[i];
}

if (b.Length>0)
    val = int.Parse(b);

15
@Thomas: รหัสนั้นใช้ไม่ได้ผลก็b == "System.Linq.Enumerable.."คือ ถูกต้อง (และง่ายยิ่งขึ้น) จะเป็นb = String.Join("", a.Where(char.IsDigit))
BlueRaja - Danny Pflughoeft

1
จุดดีที่จะสอนฉันไม่ให้ทดสอบรหัสที่ฉันเขียนในความคิดเห็น! นอกจากนี้คุณยังสามารถสร้างสตริงจากอาร์เรย์ถ่านโดยใช้ตัวnew string(char[])สร้าง
โทมัส

1
Regex ทำงานได้ดีขึ้นมาก
Jason Kelley

@BlueRaja - Danny Pflughoeft ทำไมไม่ทำให้ความคิดเห็นของคุณเป็นคำตอบที่เหมาะสมเพื่อให้ฉันสามารถโหวตมันได้ :-)
SteveC

หมายเหตุ: หากสตริงมีหลายตัวเลขคำตอบนี้จะรวมกันเป็นตัวเลขเดียว เช่น "a12bcd345" ให้ผลลัพธ์เป็น "12345" (ซึ่งอาจเป็นที่ต้องการหรือไม่ขึ้นอยู่กับเป้าหมาย) ซึ่งแตกต่างจากโซลูชัน Regex ที่ได้รับคะแนนสูงสุดซึ่งจะส่งคืน "12" สำหรับกรณีข้างต้น กรณีนี้มีความสำคัญเช่นหมายเลขโทรศัพท์ "555-111-2222"
ToolmakerSteve

546

\d+เป็น regex สำหรับจำนวนเต็ม ดังนั้น

//System.Text.RegularExpressions.Regex
resultString = Regex.Match(subjectString, @"\d+").Value;

subjectStringส่งกลับสตริงที่มีเกิดขึ้นครั้งแรกของตัวเลขใน

Int32.Parse(resultString) จะให้หมายเลข


10
เพื่อรองรับตัวเลขติดลบที่คุณสามารถใช้Regex.Match(subjectString, @"-?\d+").Valueแทนได้
Jon List

45
คำตอบนี้ไม่สมบูรณ์ (ใน C #) มันเป็นเพียงการรับหมายเลขแรกในสตริง คุณต้องทำซ้ำในการแข่งขัน: resultString = string.Join (string.Empty, Regex.Matches (subjectString, @ "\ d +") OfType <Match> () เลือก (m => m.Value));
Markus

8
@Markus: คำถามที่รัฐ "ผมต้องแยกจำนวนที่มีอยู่ภายในสตริง" และตัวอย่างทั้งหมดที่แสดงหมายเลขเดียวเป็นปัจจุบันในสตริง การวนซ้ำรายการเดียวไม่มีประโยชน์
ทิม Pietzcker

2
@ayman: โอ้เครื่องหมายจุลภาคเป็นตัวคั่นหลักพัน ที่จะต้องมี regex ที่ซับซ้อนมากขึ้น - ซึ่งควรจัดการในคำถามแยกต่างหาก จุดเริ่มต้นที่ยอดเยี่ยมคือRegular-Expressions.infoซึ่งมีส่วนต่างๆในเอ็นจิน regex ของ. NET
ทิม Pietzcker

5
@DavidSopko: คุณกำลังพูดถึงอะไร คำถามเดิมขอวิธีในการดึงหมายเลขเดียวจากสตริงทั้งในชื่อเรื่องและในเนื้อความคำถาม การแก้ไขคำถามที่ตามมา (หนึ่งปีหลังจากคำตอบของฉันและหลังจากนั้น) โดยบุคคลอื่นที่ไม่ใช่ผู้เขียนต้นฉบับเปลี่ยนชื่อเป็น "หมายเลข" หากมีสิ่งใดการแก้ไขที่ผิดพลาดควรถูกย้อนกลับ
ทิม Pietzcker

180

นี่คือวิธีที่ฉันทำความสะอาดหมายเลขโทรศัพท์เพื่อให้ได้ตัวเลขเท่านั้น:

string numericPhone = new String(phone.Where(Char.IsDigit).ToArray());

31
string numericPhone =new String(phone.Where(Char.IsDigit).ToArray());
Damith

1
วิธีการแก้ปัญหาที่สง่างามมาก .. ฉันชอบการใช้ linq
Leo Gurdian

1
ทางออกที่ดีสำหรับจำนวนเต็ม! โปรดทราบว่าวิธีนี้จะใช้ไม่ได้หากคุณพยายามแยกเลขทศนิยมเพราะจุดทศนิยมไม่ใช่ตัวเลข
Elijah Lofgren

40

ใช้นิพจน์ปกติ ...

Regex re = new Regex(@"\d+");
Match m = re.Match("test 66");

if (m.Success)
{
    Console.WriteLine(string.Format("RegEx found " + m.Value + " at position " + m.Index.ToString()));
}
else
{
    Console.WriteLine("You didn't enter a string containing a number!");
}

33

สิ่งที่ฉันใช้เพื่อรับหมายเลขโทรศัพท์โดยไม่มีเครื่องหมายวรรคตอน ...

var phone = "(787) 763-6511";

string.Join("", phone.ToCharArray().Where(Char.IsDigit));

// result: 7877636511

18

Regex.Split สามารถดึงตัวเลขจากสตริง คุณได้รับตัวเลขทั้งหมดที่พบในสตริง

string input = "There are 4 numbers in this string: 40, 30, and 10.";
// Split on one or more non-digit characters.
string[] numbers = Regex.Split(input, @"\D+");
foreach (string value in numbers)
{
    if (!string.IsNullOrEmpty(value))
    {
    int i = int.Parse(value);
    Console.WriteLine("Number: {0}", i);
    }
}

เอาท์พุท:

หมายเลข: 4 จำนวน: 40 จำนวน: 30 จำนวน: 10


16

นี่คือLinqรุ่น:

string s = "123iuow45ss";
var getNumbers = (from t in s
                  where char.IsDigit(t)
                  select t).ToArray();
Console.WriteLine(new string(getNumbers));

14
เพียงแค่เกี่ยวกับ"123iuow45ss".AsEnumerable().Where(char.IsDigit)อะไร
Ilya Ivanov

2
ฉันไม่ชอบfrom t .. select tความซ้ำซ้อน แต่อย่างไรก็ตามเสียงเชียร์
Ilya Ivanov

14

อีกวิธีง่ายๆในการใช้ Regex คุณควรจะต้องใช้สิ่งนี้

using System.Text.RegularExpressions;

และรหัสคือ

string var = "Hello3453232wor705Ld";
string mystr = Regex.Replace(var, @"\d", "");
string mynumber = Regex.Replace(var, @"\D", "");
Console.WriteLine(mystr);
Console.WriteLine(mynumber);

12

คุณสามารถลองสิ่งนี้ได้

string.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));

ดี แต่ถ้าคุณมีช่องว่างระหว่างตัวเลขในสตริงเดิมมันจะทำให้คุณมีสตริงที่ต่อกัน 1 อันขนาดใหญ่โดยที่ทั้งสองหมายเลขเข้าร่วม (ไม่มีช่องว่าง)
Mohammad Zekrallah

11

เพียงใช้ RegEx เพื่อจับคู่สตริงจากนั้นแปลง:

Match match = Regex.Match(test , @"(\d+)");
if (match.Success) {
   return int.Parse(match.Groups[1].Value);
}

9

นี่คือLinqวิธีการอื่นที่แยกหมายเลขแรกออกจากสตริง

string input = "123 foo 456";
int result = 0;
bool success = int.TryParse(new string(input
                     .SkipWhile(x => !char.IsDigit(x))
                     .TakeWhile(x => char.IsDigit(x))
                     .ToArray()), out result);

ตัวอย่าง:

string input = "123 foo 456"; // 123
string input = "foo 456";     // 456
string input = "123 foo";     // 123

9

สำหรับผู้ที่ต้องการตัวเลขทศนิยมจากสตริงที่มีRegexในสองบรรทัด:

decimal result = 0;
decimal.TryParse(Regex.Match(s, @"\d+").Value, out result);

สิ่งเดียวกัน applys จะลอย , ยาว , ฯลฯ ...


9
 string input = "Hello 20, I am 30 and he is 40";
 var numbers = Regex.Matches(input, @"\d+").OfType<Match>().Select(m => int.Parse(m.Value)).ToArray();

1
นี่คือคำตอบที่ดีที่สุดที่ให้สิ่งที่ฉันต้องการซึ่งเป็นอาร์เรย์ของตัวเลขจำนวนมากภายในสตริง ถ้าเพียง แต่มันสามารถละเว้นเครื่องหมายจุลภาคเป็นตัวเลข (ตัวคั่นหลักพัน) นั่นจะสมบูรณ์แบบ! :-)
Sagar

9

คุณสามารถทำได้โดยใช้Stringคุณสมบัติเช่นด้านล่าง:

 return new String(input.Where(Char.IsDigit).ToArray()); 

ซึ่งให้ตัวเลขจากสตริงเท่านั้น



7

คำถามไม่ได้ระบุอย่างชัดเจนว่าคุณเพียงแค่ต้องการตัวละครที่ 0 ถึง 9 แต่ก็ไม่น่าเชื่อว่าจะเป็นจริงจากชุดตัวอย่างและความคิดเห็นของคุณ ดังนั้นนี่คือรหัสที่ทำ

        string digitsOnly = String.Empty;
        foreach (char c in s)
        {
            // Do not use IsDigit as it will include more than the characters 0 through to 9
            if (c >= '0' && c <= '9') digitsOnly += c;
        }

ทำไมคุณไม่ต้องการใช้ Char.IsDigit () - ตัวเลขรวมถึงตัวละครเช่นเศษส่วนตัวห้อยตัวยกตัวเอียงตัวเลขโรมันตัวนับสกุลเงินตัวเลขที่ล้อมรอบและตัวเลขเฉพาะสคริปต์


6
var outputString = String.Join("", inputString.Where(Char.IsDigit));

รับตัวเลขทั้งหมดในสตริง ดังนั้นถ้าคุณใช้สำหรับ examaple '1 plus 2' มันจะได้ '12'


5

วิธีการขยายเพื่อรับตัวเลขบวกทั้งหมดที่มีอยู่ในสตริง:

    public static List<long> Numbers(this string str)
    {
        var nums = new List<long>();
        var start = -1;
        for (int i = 0; i < str.Length; i++)
        {
            if (start < 0 && Char.IsDigit(str[i]))
            {
                start = i;
            }
            else if (start >= 0 && !Char.IsDigit(str[i]))
            {
                nums.Add(long.Parse(str.Substring(start, i - start)));
                start = -1;
            }
        }
        if (start >= 0)
            nums.Add(long.Parse(str.Substring(start, str.Length - start)));
        return nums;
    }

หากคุณต้องการให้ตัวเลขติดลบเพียงแค่ปรับเปลี่ยนรหัสนี้เพื่อจัดการกับเครื่องหมายลบ ( -)

รับข้อมูลนี้:

"I was born in 1989, 27 years ago from now (2016)"

รายการหมายเลขผลลัพธ์จะเป็น:

[1989, 27, 2016]

5

หากตัวเลขมีจุดทศนิยมคุณสามารถใช้ด้านล่าง

using System;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine(Regex.Match("anything 876.8 anything", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("anything 876 anything", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("$876435", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("$876.435", @"\d+\.*\d*").Value);
        }
    }
}

ผล :

"อะไรก็ได้ 876.8 อะไร" ==> 876.8

"อะไรก็ได้ 876 อะไร" ==> 876

"$ 876435" ==> 876435

"$ 876.435" ==> 876.435

ตัวอย่าง: https://dotnetfiddle.net/IrtqVt


1
ขอบคุณมากสำหรับคำตอบนี้ ฉันใช้ C # และ VS2017 และพยายามหาว่าฉันจะหาค่าได้อย่างไร ขอบคุณอีกครั้งสำหรับคำตอบของคุณ
ฟองสบู่


2
  string verificationCode ="dmdsnjds5344gfgk65585";
            string code = "";
            Regex r1 = new Regex("\\d+");
          Match m1 = r1.Match(verificationCode);
           while (m1.Success)
            {
                code += m1.Value;
                m1 = m1.NextMatch();
            }

รหัสนี้ใช้เพื่อค้นหาค่าจำนวนเต็มทั้งหมดในสตริง
Manoj Gupta

การเพิ่มคำอธิบายลงในคำตอบโดยตรงจะเป็นการดีกว่าการโพสต์แยกเป็นความคิดเห็น ความคิดเห็นไม่สามารถมองเห็นได้ทันที
John Dvorak

2

วิธีการที่น่าสนใจที่มีให้ที่นี่โดยอาหมัด Mageed ใช้ Regex และ StringBuilder เพื่อดึงจำนวนเต็มในลำดับที่ปรากฏในสตริง

ตัวอย่างการใช้ Regex.Split ตามโพสต์โดย Ahmad Mageed มีดังนี้:

var dateText = "MARCH-14-Tue";
string splitPattern = @"[^\d]";
string[] result = Regex.Split(dateText, splitPattern);
var finalresult = string.Join("", result.Where(e => !String.IsNullOrEmpty(e)));
int DayDateInt = 0;

int.TryParse(finalresult, out DayDateInt);

2

นี่คืออัลกอริทึมของฉัน

    //Fast, C Language friendly
    public static int GetNumber(string Text)
    {
        int val = 0;
        for(int i = 0; i < Text.Length; i++)
        {
            char c = Text[i];
            if (c >= '0' && c <= '9')
            {
                val *= 10;
                //(ASCII code reference)
                val += c - 48;
            }
        }
        return val;
    }

1

นี่คือทางออกของฉัน

string var = "Hello345wor705Ld";
string alpha = string.Empty;
string numer = string.Empty;
foreach (char str in var)
{
    if (char.IsDigit(str))
        numer += str.ToString();
    else
        alpha += str.ToString();
}
Console.WriteLine("String is: " + alpha);
Console.WriteLine("Numeric character is: " + numer);
Console.Read();


0
static string GetdigitFromString(string str)
    {
        char[] refArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        char[] inputArray = str.ToCharArray();
        string ext = string.Empty;
        foreach (char item in inputArray)
        {
            if (refArray.Contains(item))
            {
                ext += item.ToString();
            }
        }
        return ext;
    }

0
string s = "kg g L000145.50\r\n";
        char theCharacter = '.';
        var getNumbers = (from t in s
                          where char.IsDigit(t) || t.Equals(theCharacter)
                          select t).ToArray();
        var _str = string.Empty;
        foreach (var item in getNumbers)
        {
            _str += item.ToString();
        }
        double _dou = Convert.ToDouble(_str);
        MessageBox.Show(_dou.ToString("#,##0.00"));


-3

จากตัวอย่างสุดท้ายที่ฉันสร้างวิธี:

private string GetNumberFromString(string sLongString, int iLimitNumbers)
{
    string sReturn = "NA";
    int iNumbersCounter = 0;
    int iCharCounter = 0; 

    string sAlphaChars = string.Empty;
    string sNumbers = string.Empty;
    foreach (char str in sLongString)
    {
        if (char.IsDigit(str))
        {
            sNumbers += str.ToString();
            iNumbersCounter++;
            if (iNumbersCounter == iLimitNumbers)
            {
                return sReturn = sNumbers;
            }
        }
        else
        {
            sAlphaChars += str.ToString();
            iCharCounter++;
            // reset the counter 
            iNumbersCounter = 0; 
        }
    }
    return sReturn;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.