2010-06-02 31 views
7

tôi đã nhận như sau:Net Loại bỏ tất cả các đầu 0 của một chuỗi

01.05.03

tôi cần phải chuyển đổi đó để 1.5.3

Vấn đề là tôi có thể không chỉ cắt 0 bởi vì nếu tôi nhận:

01.05.10

tôi cần phải chuyển đổi đó để 1.5.10

Vì vậy, cách nào tốt hơn để giải quyết vấn đề đó? Regex? Nếu vậy, bất kỳ ví dụ regex làm điều đó?

+0

Bạn đang cố gắng để định dạng một ngày? Có những cách tốt hơn để làm điều này hơn là regex. – Oded

+2

Không có ngày nào, đó là cấp độ phân cấp – Melursus

Trả lời

16

Mở rộng trên câu trả lời của @FrustratedWithFormsDesigner:

string Strip0s(string s) 
{ 
    return string.Join<int>(".", from x in s.Split('.') select int.Parse(x)); 
} 
+1

+1 cho Linq-ifying it! Tôi quên rằng có thể làm những việc như thế. – FrustratedWithFormsDesigner

+1

+1 thay thế tốt đẹp, mặc dù nó không đối phó với trường hợp '" 00.03.03 "' (có thể hoặc có thể không xảy ra). – Tomalak

+0

@Tomalak: đó là một điểm tốt. Hãy để tôi sửa chữa điều đó :-) – dtb

3

Bạn có thể split chuỗi trên ., sau đó cắt các hàng đầu 0 s về kết quả chia tách, sau đó hợp nhất chúng lại với nhau.

Tôi không biết cách làm điều này trong một thao tác đơn lẻ, nhưng bạn có thể viết một hàm ẩn nó và làm cho nó trông giống như giống như một thao tác đơn lẻ. ;)

UPDATE:

Tôi thậm chí không nghĩ về regex anh chàng khác. Vâng, điều đó có lẽ sẽ làm điều đó trong một hoạt động duy nhất.

+0

+1 để dễ đọc mã kết quả, chứ không phải là regex yêu cầu nhận xét –

+0

+1 Tôi muốn dùng giải pháp regex này. – dtb

+0

@Miki Watts: Vâng, giải pháp regex không yêu cầu nhận xét nào khác ngoài biến thể split/loop/join: '/ * xóa số 0 đứng đầu trên số bản dựng * /'. – Tomalak

15

Regex-thay thế

(?<=^|\.)0+ 

với chuỗi rỗng. Regex là:

 
(?<=  # begin positive look-behind (i.e. "a position preceded by") 
    ^|\. # the start of the string or a literal dot † 
)  # end positive look-behind 
0+  # one or more "0" characters 

† lưu ý rằng không phải tất cả các hương vị regex hỗ trợ chiều dài thay đổi cái nhìn-phía sau, nhưng NET không.

Nếu bạn mong đợi loại đầu vào: "00.03.03" và muốn để giữ cho không hàng đầu trong trường hợp này (như "0.3.3"), sử dụng biểu thức này thay vì:

(?<=^|\.)0+(?=\d) 

và một lần nữa thay thế với chuỗi rỗng.


Từ các ý kiến ​​(nhờ Kobi): Có một biểu ngắn gọn hơn mà không cần nhìn phía sau và tương đương với đề nghị thứ hai của tôi:

\b0+(?=\d) 

đó là

 
\b  # a word boundary (a position between a word char and a non-word char) 
0+  # one or more "0" characters 
(?=\d) # positive look-ahead: a position that's followed by a digit 

Điều này hoạt động vì 0 xảy ra là một ký tự từ, do đó, các ranh giới từ có thể được sử dụng để tìm kiếm 0 đầu tiên liên tiếp. Nó là một biểu thức tương thích hơn, bởi vì nhiều hương vị regex không hỗ trợ chiều dài thay đổi phía sau, và một số (giống như JavaScript) không nhìn lại chút nào.

+0

Bạn có thể cho tôi một ví dụ về mã C# thực hiện điều đó bằng cách thay thế không? – Melursus

+4

@Melursus: Không, bởi vì đây là * rất dễ dàng * để tìm. Tài liệu chính thức và các trang web chưa được kiểm duyệt (bao gồm cả Stack Overflow) có thể cung cấp cho bạn một ví dụ về cách sử dụng các biểu thức chính quy trong .NET. – Tomalak

+1

'\ b0 + (? = \ D)' cũng sẽ hoạt động tốt ở đây và giữ một số không. – Kobi

0
string s = "01.05.10"; 
string newS = s.Replace(".0", "."); 
newS = newS.StartsWith("0") ? newS.Substring(1, newS.Length - 1) : newS; 

Console.WriteLine(newS); 

LƯU Ý: Bạn sẽ phải kiểm tra kỹ lưỡng kết hợp đầu vào có thể có.

+1

Điều này có thể không hoạt động nếu anh ta có '001.00005.10', nhưng anh ta không xác định liệu điều đó có thể thực hiện được hay không. – FrustratedWithFormsDesigner

1

Dưới đây là một cách khác để bạn có thể làm những gì FrustratedWithFormsDesigner gợi ý:

string s = "01.05.10"; 
string s2 = string.Join(
    ".", 
    s.Split('.') 
     .Select(str => str.TrimStart('0')) 
     .ToArray() 
); 

Đây là gần giống như câu trả lời DTB, nhưng doesn' t yêu cầu các chất nền là các số nguyên hợp lệ (nó cũng sẽ hoạt động với, ví dụ, "000A.007.0HHIMARK").

CẬP NHẬT: Nếu bạn muốn bất kỳ chuỗi bao gồm tất cả 0s trong chuỗi đầu vào là đầu ra dưới dạng đĩa đơn 0, bạn có thể sử dụng này:

string s2 = string.Join(
    ".", 
    s.Split('.') 
     .Select(str => TrimLeadingZeros(str)) 
     .ToArray() 
); 

public static string TrimLeadingZeros(string text) { 
    int number; 
    if (int.TryParse(text, out number)) 
     return number.ToString(); 
    else 
     return text.TrimStart('0'); 
} 

Ví dụ đầu vào/đầu ra:

00.00.000A.007.0HHIMARK // input 
0.0.A.7.HHIMARK   // output 
+0

Đó là giải pháp tôi đã có trước khi tôi thay đổi nó thành 'int.Parse'. Nó không thành công khi một phần được tạo thành hoàn toàn bằng các ký tự ''0'', ví dụ:' "03.00.10" '. – dtb

+0

@dtb: Ý của bạn là "không thành công"? Tôi không thấy nơi OP xác định những gì sẽ xảy ra trong trường hợp này. Nếu các số 0 ở cuối bị xóa, tôi đã nghĩ đầu ra của "03.00.10" phải là "03..10", đúng là như thế nào. Nếu không, OP sẽ cần phải cung cấp các yêu cầu chi tiết hơn một chút (trừ khi tôi thiếu một cái gì đó). –

0

này có vẻ như nó là một định dạng ngày, nếu vì vậy tôi sẽ sử dụng mã xử lý ngày

DateTime time = DateTime.Parse("01.02.03"); 
String newFormat = time.ToString("d.M.yy"); 

hoặc thậm chí tốt hơn

String newFormat = time.ToShortDateString(); 

sẽ tôn trọng bạn và thiết lập văn hóa khách hàng của bạn.

Nếu dữ liệu này không phải là một ngày sau đó không sử dụng này :)

+0

OP cho biết đây không phải là ngày. – dtb

+0

xin lỗi đã bỏ lỡ nhận xét. bởi OP –

1

Ngoài ra còn có những cách cũ-trường mà có lẽ có đặc tính hiệu suất tốt hơn so với hầu hết các giải pháp khác được đề cập. Một cái gì đó như:

static public string NormalizeVersionString(string versionString) 
{ 
    if(versionString == null) 
     throw new NullArgumentException("versionString"); 

    bool insideNumber = false;  
    StringBuilder sb = new StringBuilder(versionString.Length); 
    foreach(char c in versionString) 
    { 
     if(c == '.') 
     { 
      sb.Append('.'); 
      insideNumber = false; 
     } 
     else if(c >= '1' && c <= '9') 
     { 
      sb.Append(c); 
      insideNumber = true; 
     } 
     else if(c == '0') 
     { 
      if(insideNumber) 
       sb.Append('0'); 
     } 
    } 
    return sb.ToString(); 
} 
0

Tôi đã có một yêu cầu tương tự như phân tích một chuỗi với adresses đường phố, nơi một số các số nhà đã dẫn zero và tôi cần phải loại bỏ chúng trong khi vẫn giữ phần còn lại của văn bản còn nguyên vẹn, vì vậy tôi hơi đã chỉnh sửa câu trả lời được chấp nhận để đáp ứng các yêu cầu của tôi, có thể ai đó thấy nó hữu ích. Về cơ bản làm giống như câu trả lời được chấp nhận, với sự khác biệt mà tôi đang kiểm tra xem phần chuỗi có thể được phân tích cú pháp dưới dạng số nguyên không, và mặc định thành giá trị chuỗi khi sai;

string Strip0s(string s) 
{ 
    int outputValue; 
    return 
     string.Join(" ", 
      from x in s.Split(new[] { ' ' }) 
      select int.TryParse(x, out outputValue) ? outputValue.ToString() : x); 
} 

Input: "Quần đảo Brygge 34 B 07 TV"

Output: "Quần đảo Brygge 34 B 7 TV"

Các vấn đề liên quan