簡體   English   中英

如何使我的正則表達式匹配第一個模式而不是最后一個?

[英]How can I make my regex match the first pattern instead of the last?

我可能做錯了所有。 我有一個充滿數據的文本文件,我想匹配和替換文件中“項目”和“目錄編號”的模式。 但是文件中每個元素的順序非常重要,因此我想從文件頂部開始進行匹配/替換,然后向下進行操作。

下面的代碼片段實際上可以工作,但是當我執行它時,它將替換“ SeaMonkey”和“ SMKY-1978”模式的第三個實例,然后替換該模式的第二個實例。 我要執行的操作是替換模式的第一個實例,然后替換第二個。

因此,我想讓輸出說“發現庫爾特的 SMKY-1978 SeaMonkeys”,然后說“發現Shane的 SMKY-1978 SeaMonkeys”,然后不理M米克的SMKY-1978 SeaMonkeys,因為我只想查找並替換該模型的前兩個實例。圖案。 現在它說“發現Shane的 SMKY-1978 SeaMonkeys”和“發現Mick的 SMKY-1978 SeaMonkeys”是因為每次執行for循環時它都匹配最后一個模式。

那么,我是錯過了一個鮮為人知的微妙的正則表達式字符還是我只是在做我想做的完全完全錯誤的事情?

這是工作代碼:

# my regexp matches from the bottom to the top but I'd like it to replace from the top down
local $/=undef;
my $DataToParse = <DATA>;
my $item = "SeaMonkeys";
my $catNum = "SMKY-1978";
my $maxInstancesToReplace = 2;
parseData();
exit();

sub parseData {
    for (my $counter = 0; $counter < $maxInstancesToReplace; $counter++) {
        # Stick in a temporary text placeholder that I will replace later after more processing
        $DataToParse =~ s/(.+)\sELEMENT\s(.+?)\s\(Item := \"$item\".+?CatalogNumber := \"$catNum.+?END_ELEMENT(.+)/$1 ***** Found $2\'s $catNum $item. (counter: $counter) *****$3/s;
    } 
    print("Here's the result:\n$DataToParse\n");
}

__DATA__
    ELEMENT Kurt (Item := "BrightLite",
                  ItemID := 29,
                  CatalogNumber := "BTLT-9274",
                  Vendor := 100,
    END_ELEMENT

    ELEMENT Mick (Item := "PetRock",
                  ItemID := 36,
                  CatalogNumber := "PTRK-3475/A",
                  Vendor := 82,
    END_ELEMENT

    ELEMENT Kurt (Item := "SeaMonkeys",
                  ItemID := 12,
                  CatalogNumber := "SMKY-1978/E",
                  Vendor := 77,
    END_ELEMENT

    ELEMENT Joe (Item := "Pong",
                 ItemID := 24,
                 CatalogNumber := "PONG-1482",
                 Vendor := 5,
    END_ELEMENT

    ELEMENT Shane (Item := "SeaMonkeys",
                   ItemID := 1032,
                   CatalogNumber := "SMKY-1978/E",
                   Vendor := 77,
    END_ELEMENT

    ELEMENT Kurt (Item := "Battleship",
                  ItemID := 99,
                  CatalogNumber := "BTLS-5234",
                  Vendor := 529,
    END_ELEMENT

    ELEMENT Mick (Item := "SeaMonkeys",
                  ItemID := 8,
                  CatalogNumber := "SMKY-1978/F",
                  Vendor := 77,
    END_ELEMENT

    ELEMENT Frank (Item := "PetRock",
                   ItemID := 42,
                   CatalogNumber := "PTRK-3475/B",
                   Vendor := 82,
    END_ELEMENT

    ELEMENT Joe (Item := "SeaMonkeys",
                 ItemID := 8,
                 CatalogNumber := "SMKY-1979/A",
                 Vendor := 77,
    END_ELEMENT

這是當前輸出的內容:

Here's the result:
        ELEMENT Kurt (Item := "BrightLite",
                      ItemID := 29,
                      CatalogNumber := "BTLT-9274",
                      Vendor := 100,
        END_ELEMENT

        ELEMENT Mick (Item := "PetRock",
                      ItemID := 36,
                      CatalogNumber := "PTRK-3475/A",
                      Vendor := 82,
        END_ELEMENT

        ELEMENT Kurt (Item := "SeaMonkeys",
                      ItemID := 12,
                      CatalogNumber := "SMKY-1978/E",
                      Vendor := 77,
        END_ELEMENT

        ELEMENT Joe (Item := "Pong",
                     ItemID := 24,
                     CatalogNumber := "PONG-1482",
                     Vendor := 5,
        END_ELEMENT

 ***** Found Shane's SMKY-1978 SeaMonkeys. (counter: 1) *****

        ELEMENT Kurt (Item := "Battleship",
                      ItemID := 99,
                      CatalogNumber := "BTLS-5234",
                      Vendor := 529,
        END_ELEMENT

 ***** Found Mick's SMKY-1978 SeaMonkeys. (counter: 0) *****

        ELEMENT Frank (Item := "PetRock",
                       ItemID := 42,
                       CatalogNumber := "PTRK-3475/B",
                       Vendor := 82,
        END_ELEMENT

        ELEMENT Joe (Item := "SeaMonkeys",
                     ItemID := 8,
                     CatalogNumber := "SMKY-1979/A",
                     Vendor := 77,
        END_ELEMENT

正則表達式開頭的。+是“貪婪”。 這意味着它將匹配最大字符數。

您的正則表達式寫得更好(可讀性更高,速度更快),因為

my $re=qr/\sELEMENT\s(.+?)\s\(Item := "$item".+?CatalogNumber := "$catNum.+?END_ELEMENT/;

我認為您可以簡單地重復此比賽:

sub parseData {
    my $re=qr/\sELEMENT\s(.+?)\s\(Item := "$item".+?CatalogNumber := "$catNum.+?END_ELEMENT(.+)/;
    foreach my $counter (0..$maxInstancesToReplace) {
      # Stick in a temporary text placeholder that I will replace later after more processing
      $DataToParse =~ s/$re/ ***** Found $1\'s $catNum $item. (counter: $counter) *****$2/s;
    } 
    print("Here's the result:\n$DataToParse\n");
}

如果無法重復,則應使用/ e regex修飾符。

最好的解決方案似乎是從數據中獲取每個ELEMENT ... END_ELEMENT節,並且一次只對一個表達式進行正則表達式,而不是一次將整個完整數據集提供給正則表達式。 不完全是我要完成的工作,但是我重寫了程序來進行這種零碎的處理,它的工作就像一個魅力。

暫無
暫無

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

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