簡體   English   中英

正則表達式匹配從換行符到括號的所有內容以及搜索詞

[英]Regex to match everything from newline upto parenthesis along with a search term

我們正在嘗試解析 90 年代基於 DOS 的會計軟件輸出的信息,因此我們可以將其轉換並上傳到更新的系統。 它主要是與每個會計分錄有關的信息,它以隨機制表符、換行符等形式輸出,如下所示:

#Ch. No. 209488 #Rt. Date 12-09-1997 #Bank: Citibank (R:2379;L:28)

#Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432;
L:28)

#Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997
#Bank: Citibank (R:2432;
L:28
)

#Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997
        #Bank: Citibank (R:2432;
    L:28
)

但是,很清楚的是,每個條目的信息都從新行開始並以)結尾

如何編寫將開始在該行中一直到 a )查找術語的正則表達式?

例如在上面的數據中,我們正在使用preg_match_all('/^.*\\b(?:Dr)\\b.*$/m', $dos, $matches)查找字符串Dr ,它匹配如下:

Array
(
    [0] => Array
        (
            [0] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432;
            [1] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997
            [2] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997
        )

)

您可以從數組中的第二個結果中看到,它被省略了#Bank: Citibank (R:2432; L:28)因為它位於單獨的行上,但該數據仍然是其上方行的一部分。

我們正在使用的正則表達式如何修改以匹配下一個)無論它是在同一行還是下一行,甚至是下面的幾行? 所以結果將是:

Array
(
    [0] => Array
        (
            [0] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432;L:28)
            [1] => #Ch. No. 759263 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432;L:28)
            [2] => #Ch. No. 395159 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432;L:28)
        )

)

您可以使用否定字符類[^來匹配除括號之外的任何字符,括號也將匹配換行符。

匹配后,您可以用一個空格替換所有空白字符。

^.*\bDr\b[^()]*\([^()]+\)

那會匹配

  • ^字符串開始
  • .*\\bDr\\b匹配 0+ 次除換行符以外的任何字符,然后匹配單詞邊界之間的 Dr (或者匹配#Dr\\b如果它總是以#開頭)
  • [^()]*匹配 0+ 次除括號外的任何字符
  • \\(匹配(
  • [^()]+匹配 1+ 次除括號之外的任何字符(如果必須至少有一個字符不是( )
  • \\)匹配)

正則表達式演示| php 演示

例如

$re = '/^.*\bDr\b[^()]*\([^()]+\)/m';
$str = '#Ch. No. 209488 #Rt. Date 12-09-1997 #Bank: Citibank (R:2379;L:28)

#Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432;
L:28)

#Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997
#Bank: Citibank (R:2432;
L:28
)

#Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997
        #Bank: Citibank (R:2432;
    L:28
)';

$result = preg_match_all($re, $str, $matches);
$result = array_map(function($x) {
    return preg_replace("/\s+/", ' ', $x);
}, $matches[0]);
print_r($result);

輸出

Array
(
    [0] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432; L:28)
    [1] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432; L:28 )
    [2] => #Ch. No. 884273 #Dr. Date 10-09-1997 #Ch. Dep. 14-09-1997 #Bank: Citibank (R:2432; L:28 )
)

根據@CBroe 的評論,我想出了這個:

/(#[^\\)\\n]*(?:#Dr).*\\)\\n*)/gsU

  • #[^\\)\\n]* -> 以#開頭並阻止搜索所有通過)\\n (新行)的字符。

  • (?:#Dr) -> 無捕獲組中的搜索字符串。

  • .*\\)\\n* -> 繼續直到遇到 a )\\n (換行)。

  • gsU -> used flags:g:全局搜索,s:匹配新行,U:非貪婪量詞。

演示

暫無
暫無

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

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