簡體   English   中英

為什么 while 循環中的 Regex 將僅匹配第一次出現的長度(在 while 循環中不是動態的)

[英]Why Regex in a while loop will match only the first occurrence length (is not dynamic in a while loop)

我有一個正則表達式,我想它會動態捕獲我的零組。 發生的事情是我從像“001111110000001100110011111”這樣的字符串中得到一個包含 [00, 00, 00, 00, 00] 的列表

我試過將我的 var regex = new Regex() 放在 while 循環中,希望這可以解決我的問題。 無論我嘗試什么,正則表達式都只返回第一次出現的零長度,而不是用不同的零數量填充我的集合。

List<string> ZerosMatch(string input)
{
    var newInput = input;
    var list = new List<string>();
    var regex = new Regex(@"[0]{1,}");
    var matches = regex.Match(newInput);

    while (matches.Success)
    {
        list.Add(matches.Value);

        try 
        {
            newInput = newInput.Remove(0, matches.Index);
        }
        catch
        {
            break;
        }                                      
    }
    return list;
}

對比

List<string> ZerosMatch(string input)
{
    var newInput = input;
    var list = new List<string>();
    bool hasMatch = true;

    while (hasMatch)
    {
        try 
        {
            var regex = new Regex(@"[0]{1,}");
            var matches = regex.Match(newInput);
            newInput = newInput.Remove(0, matches.Index);
            list.Add(matches.Value);
            hasMatch = matches.Success;
        }
        catch
        {
            break;
        }                                      
    }
    return list;
}

我的問題是為什么會這樣?

        var newInput = input;   //The newInput variable is not needed and you can proceed with input
        var list = new List<string>();
        var regex = new Regex(@"[0]{1,}");
        var matches = regex.Matches(newInput);

        for(int i=0; i<matches.Count; i++)
        {
            list.Add(matches[i].Value);
        }
        return list;

我建議使用Matches而不是Match並在Linq的幫助下進行查詢(為什么我們要循環,當我們可以一次獲得所有匹配項時再次搜索):

using Sysem.Linq;

...

static List<string> ZeroesMatch(string input) => Regex
  .Matches(input ?? "", "0+")
  .Cast<Match>()
  .Select(match => match.Value)
  .ToList();

在這里,我將模式簡化為0+ (一個或多個0個字符)並添加了?? "" ?? ""以避免null字符串出現異常

在您的第一種方法中,您只執行一次regex.Match ,因此您總是在查看完全相同的匹配項,直到您的代碼拋出異常。 根據您的第一個匹配項是在索引0還是更晚的位置,它是 OutOfBounds 異常(因為您嘗試從空字符串中刪除)或 OutOfMemory 異常(因為您沒有從字符串中刪除任何內容,而是不確定地添加到結果list

如果您的輸入以0開頭或者您到達某個以0開頭的中間結果字符串,則您的第二種方法將遇到相同的 OutOfMemory 異常

請參閱下面的工作方法:

List<string> ZerosMatch(string input)
{
    var newInput = input;
    var list = new List<string>();
    var regex = new Regex(@"[0]{1,}");
    var match = regex.Match(newInput);
    while (match.Success)
    {
        newInput = newInput.Remove(match.Index, match.Value.Length);
        list.Add(match.Value);
        match = regex.Match(newInput);
    }
    return list;
}

盡管如此,如果您想從字符串中提取匹配項的多個實例,建議使用Regex.Matches方法...

暫無
暫無

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

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