2012-01-05 65 views
7

Tìm chuỗi regex để tôi tìm nhóm chữ số bên phải (nếu có) được nhúng trong chuỗi. Chúng tôi chỉ quan tâm đến các chữ số tiếp giáp. Chúng tôi không quan tâm đến dấu, dấu phẩy, số thập phân, v.v. Nếu tìm thấy đơn giản chỉ nên được coi là không phải chữ số giống như một chữ cái.Chuỗi RegEx nào sẽ tìm nhóm chữ số cuối cùng (ngoài cùng bên phải) trong chuỗi?

Đây là mục đích thay thế/tăng dần vì vậy chúng tôi cũng cần lấy mọi thứ trước và sau số được phát hiện để chúng tôi có thể tạo lại chuỗi sau khi tăng giá trị để chúng tôi cần regex được mã hóa.

Dưới đây là ví dụ về những gì chúng ta đang tìm kiếm:

  • "abc123def456ghi" cần xác định the'456'
  • "abc123def456ghi789jkl" cần xác định the'789'
  • "abc123def" nên xác định' 123'
  • "123ghi" cần xác định the'123'
  • "abc123,456ghi" cần xác định the'456'
  • "abc-654def" nên ide ntify the'654'
  • 'abcdef' không nên trả lại bất kỳ trận đấu

Như một ví dụ về những gì chúng ta muốn, nó sẽ là một cái gì đó giống như bắt đầu với cái tên 'mục 4-1a', giải nén ra '1' với mọi thứ trước khi là tiền tố và mọi thứ sau hậu tố. Sau đó, bằng cách đó, chúng ta có thể tạo ra các giá trị 'Item 4-2a', 'Item 4-3a' và 'Item 4-4a' trong một vòng lặp mã.

Bây giờ, nếu tôi đang tìm tập đầu tiên, điều này sẽ dễ dàng. Tôi chỉ tìm khối tiếp giáp đầu tiên gồm 0 hoặc nhiều chữ số không cho tiền tố, sau đó khối 1 hoặc nhiều chữ số tiếp giáp cho số, sau đó mọi thứ khác đến cuối sẽ là hậu tố.

Vấn đề tôi gặp phải là cách xác định tiền tố là bao gồm tất cả các số (nếu có) trừ tập hợp cuối cùng. Tất cả mọi thứ tôi cố gắng cho tiền tố giữ nuốt rằng tập cuối cùng, ngay cả khi tôi đã cố gắng neo nó vào cuối bằng cách cơ bản đảo ngược ở trên.

+0

Bạn có thể [split] (http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.split.aspx) bằng cách sử dụng regex do @Birei cung cấp và cập nhật chỉ mục thứ hai trước khi ghép nối để có được kết quả mong muốn. –

+0

Bạn có thể chia tay bằng cách nào? Nếu chuỗi là a44b44c thì sao? Tiền tố phải là 'a44b' và nếu tôi sẽ tham gia vào quá nhiều thao tác thủ công, thì đánh bại bằng regex đã hỗ trợ các thẻ được đặt tên. – MarqueIV

+1

Bằng cách tách, tôi có nghĩa là (Regex.Split) [http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.split.aspx], do đó siêu liên kết trong chú thích trước. Áp dụng 'Regex.Split()' với 3 mã thông báo cho 'a44b44c' viz. 'a44b',' 44' và 'c'. –

Trả lời

13

Làm thế nào về:

^(.*?)(\d+)(\D*)$ 

sau đó tăng nhóm thứ hai và concat tất cả 3.

Giải thích:

^   : Begining of string 
    (  : start of 1st capture group 
    .*? : any number of any char not greedy 
)  : end group 
    (  : start of 2nd capture group 
    \d+ : one or more digits 
)  : end group 
    (  : start of 3rd capture group 
    \D* : any number of non digit char 
)  : end group 
$   : end of string 

Nhóm chụp đầu tiên sẽ phù hợp với tất cả các nhân vật cho đến khi chữ số đầu tiên của nhóm cuối cùng của chữ số trước khi kết thúc chuỗi.

hoặc nếu bạn có thể sử dụng tên nhóm

^(?<prefix>.*?)(?<number>\d+)(?<suffix>\D*)$ 
+0

Tùy thuộc vào nơi tập hợp các chữ số cuối cùng, điều này có lẽ hiệu quả hơn tôi. +1 – ridgerunner

+0

Ok, cái này hoạt động tuyệt vời ... nhưng tôi không thể thấy như thế nào! Bạn có thể vui lòng chỉnh sửa điều này để hiển thị các nhận xét về những gì từng người đang làm không? Ví dụ, tôi đang bối rối ngay cả trong nhóm đầu tiên của bạn ... (. *?) ... như tôi nghĩ rằng dấu hỏi và dấu hoa thị được loại trừ lẫn nhau sau một thời gian, nhưng rõ ràng là tôi sai ở đó. – MarqueIV

+0

@MarqueIV: Bạn được chào đón. – Toto

5

Hãy thử regex tiếp theo:

(\d+)(?!.*\d) 

Giải thích:

(\d+)   # One or more digits. 
(?!.*\d)  # (zero-width) Negative look-ahead: Don't find any characters followed with a digit. 

EDIT (Offtopic của câu hỏi):: Câu trả lời này là không chính xác nhưng câu hỏi này đã được trả lời trong các bài viết khác để tránh xóa cái này tôi sẽ sử dụng cùng một regex theo cách khác, ví dụ trong Perl có thể được sử dụng như thế này để lấy lại sult như trong C# (increment chữ số cuối cùng):

s/(\d+)(?!.*\d)/$1 + 1/e; 
+0

Không hoàn toàn. Điều đó đúng cách xác định số lượng, nhưng nó vẫn không hiển thị như thế nào để tokenize chuỗi để có được tiền tố và hậu tố cũng là những gì tôi chủ yếu là đấu tranh với. Bạn có thể giúp gì không? – MarqueIV

+0

@MarqueIV: Bạn đúng, không phải những gì bạn muốn, tôi đã bỏ lỡ điểm, xin lỗi. Nhưng bây giờ có một số câu trả lời đúng mà giải quyết vấn đề của bạn tốt. – Birei

3

Bạn cũng có thể thử phiên bản đơn giản hơn một chút:

(\d+)[^\d]*$ 
+1

những người khác không làm việc cho tôi ... điều này có. sự đơn giản là một loại thuốc. –

+0

Đây là một thử nghiệm xác nhận công việc này như mong đợi: http://regex101.com/r/hN8zG5/1 –

1

này nên làm điều đó:

Regex regexObj = new Regex(@" 
    # Grab last set of digits, prefix and suffix. 
    ^    # Anchor to start of string. 
    (.*)   # $1: Stuff before last set of digits. 
    (?<!\d)   # Anchor start of last set of digits. 
    (\d+)   # $2: Last set of one or more digits. 
    (\D*)   # $3: Zero or more trailing non digits. 
    $    # Anchor to end of string. 
    ", RegexOptions.IgnorePatternWhitespace); 
1

gì về việc không sử dụng Regex. Dưới đây là đoạn mã (đối với giao diện điều khiển)

string[] myStringArray = new string[] { "abc123def456ghi", "abc123def456ghi789jkl", "abc123def", "123ghi", "abcdef","abc-654def" }; 

     char[] numberSet = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; 
     char[] filterSet = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m', 
             'n','o','p','q','r','s','t','u','v','w','x','y','z','-'}; 
     foreach (string myString in myStringArray) 
     { 
      Console.WriteLine("your string - {0}",myString); 
      int index1 = myString.LastIndexOfAny(numberSet); 
      if (index1 == -1) 
      Console.WriteLine("no number"); 
      else 
      { 
       string mySubString = myString.Substring(0,index1 + 1); 
       string prefix = myString.Substring(index1 + 1); 
       Console.WriteLine("prefix - {0}", prefix); 
       int index2 = mySubString.LastIndexOfAny(filterSet); 
       string suffix = myString.Substring(0, index2 + 1); 
       Console.WriteLine("suffix - {0}",suffix); 
       mySubString = mySubString.Substring(index2 + 1); 
       Console.WriteLine("number - {0}",mySubString); 
       Console.WriteLine("_________________"); 
      } 
     } 
     Console.Read(); 
Các vấn đề liên quan