Php 正则表达式匹配从换行符到括号以及搜索词的所有内容
我们正试图解析90年代基于DOS的会计软件输出的信息,以便将其转换并上传到更新的系统。它主要是与每个会计分录相关的信息,并通过随机制表符、换行符等输出。如下所示:Php 正则表达式匹配从换行符到括号以及搜索词的所有内容,php,regex,Php,Regex,我们正试图解析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. 8
#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
)
但是,很明显,每个条目的信息都从一个新行开始,以一个)
如何编写一个从该行开始寻找术语一直到)
的正则表达式
例如,在上面的数据中,我们使用preg\u match\u 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 )
)
您可以使用[^
匹配除括号外的任何字符,括号也将匹配换行符
匹配后,可以用单个空格替换所有空白字符
^.*\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*
->继续,直到遇到)
或\n
(新行)
gsU
->使用的标志:g:全局搜索,s:匹配新行,U:取消标记量词
根据@CBroe的评论,我得出了以下结论:
/(#[^\)\n]*(?:#Dr.*\)\n*)/gsU
#[^\)\n]*
->以#
开头,并防止搜索通过)
或\n
的所有字符(新行)
(?:#Dr)
->无捕获组中的搜索字符串
*\)\n*
->继续,直到遇到)
或\n
(新行)
gsU
->使用的标志:g:全局搜索,s:匹配新行,U:取消标记量词