[英]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+ 次除括號之外的任何字符(如果必須至少有一個字符不是(
)
\\)
匹配)
例如
$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.