簡體   English   中英

在字符串中查找特定的數字模式

[英]find specific pattern of digits in a string

考慮以下字符串:

"via caporale degli zuavi 278a , 78329" 

"autostrada a1 km - 47"

我正在尋找可以存在(第一個示例)或不存在(第二個示例)的特定序列

特別是,我正在尋找一個數字序列,它可以是 1 到 4 位數字,並且可以跟一個字母,但在字符串中也不能有 substring “km”。 所以在我之前的例子中,“278a”是有效的,但數字序列的 rest 不是。

我到目前為止所做的如下:

因為我知道任何包含“km”的字符串都是無效的,所以我應用了這段代碼:

if(!stripped.ToLower().Contains("km"))
{
    // apply Regex
}
else
    // string not valid, move on

我知道這個正則表達式會給我所有的數字序列: Regex.Matches(t, @"\d+"); ,但這還不夠。 我該如何從這里開始?

編輯:為了進一步澄清,當一個數字序列后跟一個字母時,該字母必須是下一個字符(所以沒有空格或其他任何東西)

Edit2:注意數字的順序可以跟字母也可以不跟(所以 278a 和 278 一樣有效)

您可以向左右斷言 not km,並在一個組中捕獲 1-4 個數字 0-9 並匹配一個 char a-zA-Z:

(?<!\bkm\b.*)\b[0-9]{1,4}[A-Za-z]?\b(?!.*\bkm)
  • (?<.\bkm\b.*)斷言左邊不是公里
  • \b[0-9]{1,4}[A-Za-z]\b匹配 1-4 個數字 0-9 並匹配單個字符 A-Za-z
  • (?..*\bkm)斷言不向右公里

.NET 正則表達式演示

string pattern = @"(?<!\bkm\b.*)\b[0-9]{1,4}[A-Za-z]?\b(?!.*\bkm)";
string input = @"via caporale degli zuavi 278a , 78329
via caporale degli zuavi 277 , 78329
via caporale degli zuavi 279a , 78329 km
km via caporale degli zuavi 280a , 78329
autostrada a1 km - 47";

foreach (Match m in Regex.Matches(input, pattern))
{
    Console.WriteLine(m.Value);
}

Output

278a
277

如果預期只有 1 個匹配項,您還可以排除整個字符串中的 km,並在Regex.Match中使用捕獲組

^(?!.*\bkm\b).*\b([0-9]{1,4}[A-Za-z]?)\b

正則表達式演示

您可以使用

^(?!.*(?<!\p{L})km\b)(?:.*\D)?(\d{1,4})(?=\p{L}?\b)

請參閱.NET 正則表達式演示 詳情

  • ^ - 字符串的開頭
  • (?.?*(?<!\p{L})km\b) - 不允許在單詞前面沒有任何字母的km ,並且不允許在字符串中的任何位置出現字母數字/下划線
  • (?:.*\D)? - 除換行符之外的任何零個或多個字符的可選序列,盡可能多,然后是非數字字符
  • (\d{1,4}) - 第 1 組:一到四位數
  • (?=\p{L}?\b) - 緊鄰右側,應該有一個可選字母,后面不帶任何字母數字或連接符標點符號(如_ )。

請參閱C# 演示

var l = new List<string> {"via caporale degli zuavi 278a , 78329","autostrada a1 km - 47"};
foreach (var t in l) 
{
    var rx = @"^(?!.*(?<!\p{L})km\b)(?:.*\D)?(\d{1,4})(?=\p{L}?\b)";
    var match = Regex.Match(t, rx, RegexOptions.ECMAScript)?.Groups[1].Value;
    if (!string.IsNullOrEmpty(match))
    {
        Console.WriteLine($"There is a match in '{t}': {match}");
    } 
    else
    {
        Console.WriteLine($"There is no match in '{t}'.");
    }
}

Output:

There is a match in 'via caporale degli zuavi 278a , 78329': 278
There is no match in 'autostrada a1 km - 47'.

RegexOptions.ECMAScript選項用於使\d僅匹配 ASCII 數字(盡管它不影響\p{L} )。

暫無
暫無

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

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