提问人:codename_zoe 提问时间:10/19/2023 最后编辑:mickmackusacodename_zoe 更新时间:10/20/2023 访问量:91
找到一个关键字,然后显示每一行,直到它在 PHP 中找到下一个关键字
Find a keyword, then display each line until it finds the next keyword in PHP
问:
我想做的是:
- 打开 sql 文件
- 找到一个关键字,然后显示该行
- 继续显示每一行,直到下一个关键字
- 继续做 1 - 3,直到文件结束
这是我的代码,但它在第一次匹配后停止显示:
<?php
$filename = 'test.sql';
$startWord = ':begin';
$endWord = 'sqlexception';
// Open the SQL file for reading
$file = fopen($filename, 'r');
if ($file) {
$foundStart = false;
while (!feof($file)) {
$line = fgets($file);
if ($foundStart || stripos($line, $startWord) !== false) {
$foundStart = true;
echo $line; // Display the current line
if (stripos($line, $endWord) !== false) {
$foundStart = false; // Stop displaying lines after finding the end word
}
}
}
fclose($file);
} else {
echo "Unable to open the file.";
}
?>
这是我想从中检索数据的sql文件
getDataNlp:begin
declare continue handler for sqlexception
begin
set returnCode = -1;
set returnMsg = 'SQL Exception';
end;
if useTransaction = 1 then
start transaction;
end if;
set returnMsg = '';
set returnCode = 0;
set @count = 0;
set @orgName = orgName;
set @orgId = '';
set @oprEmail = oprEmail;
CreateOpr:BEGIN
DECLARE idx INT DEFAULT 1;
DECLARE v_orgName VARCHAR(128) DEFAULT '';
declare continue handler for sqlexception
begin
set returnCode = -1;
set returnMsg = 'SQL Exception';
end;
start transaction;
set returnCode = 0;
set returnMsg = '';
set @count = 0;
set @oprName = oprName;
select count(1) into @count from Opr where name = @oprName;
if (@count > 0) then
set returnCode = -1;
set returnMsg = 'Opr with same oprName already exist';
rollback;
leave CreateOpr;
end if;
END ;;
我想像这样检索这些行
getDataNlp: begin
declare continue handler for sqlexception
答:
0赞
adek-
10/19/2023
#1
代码在第一次匹配后停止显示的原因是,在找到 .由于您正在逐行读取文件,因此变为 false,并且它停止显示任何后续行。$foundStart
$endWord
$foundStart
检查这个而不是你的:while
while (!feof($file)) {
$line = fgets($file);
if (stripos($line, $startWord) !== false) {
$foundStart = true;
}
if ($foundStart) {
echo $line . '<br>';
}
if (stripos($line, $endWord) !== false && $foundStart) {
echo "---- End of Block ----<br>";
$foundStart = false;
}
}
评论
0赞
mickmackusa
10/19/2023
错误:未定义$foundStart。在发布之前,您是否测试了代码?
0赞
codename_zoe
10/19/2023
谢谢,它正在工作,但是是否可以添加类似“如果在接下来的 5 行中找不到$endWord,请跳过并查找$startWord”之类的内容?
0赞
mickmackusa
10/19/2023
请澄清您的问题,以包含足够具有挑战性的输入,以演示已知的麻烦场景,并显示您确切期望的结果@cod
0赞
adek-
10/19/2023
在线 php 编辑器中的@mickmackusa无法在 VSCode 中使用文件完美无缺,如果您因为该资源而贬低我,那么这是不公平的。codename_zoe如果我理解得很好,您想添加一个计数器来跟踪在找到$startWord后和遇到$endWord之前读取的行数。如果计数器达到某个限制,比如 5 行,您希望将$foundStart重置为 false 并继续寻找下一个$startWord?
0赞
codename_zoe
10/19/2023
@adek - 谢谢。我添加了一个计数器,现在它工作正常
1赞
mickmackusa
10/19/2023
#2
我可能只是一口气解析整个 sql 文件,而不是尝试逐行解析。preg_match_all()
使用范围量词来声明找到的开始和结束关键字之间允许的行数。{0,$yourLimit}
A 将匹配所有非垂直空格字符。我假设您不需要多字节支持,但可以添加到模式修饰符中。 不区分大小写。 使匹配项成为行的末尾,而不是字符串的末尾。 匹配换行符序列。我在末尾使用前瞻来 rtrim() 空白,我认为您不希望在结果中出现。.
u
i
m
$
\R
代码:(演示)
$startWord = ':begin';
$endWord = 'sqlexception';
$maxLinesBetween = 4;
preg_match_all('#.*' . preg_quote($startWord) . '.*(?:\R.*){0,' . $maxLinesBetween . '}.*' . preg_quote($endWord) . '.*?(?=\s*$)#im', $sql, $m);
var_export($m[0]);
评论
0赞
user3783243
10/19/2023
嗯,以前没见过/用过。这与 ?\R
\v
0赞
codename_zoe
10/19/2023
我尝试了此代码,但它返回以下错误:“已弃用:preg_match_all():已弃用将 null 传递给字符串类型的参数 #2 ($subject) ”
0赞
mickmackusa
10/20/2023
@cod 我有的地方,您将需要访问文件内容()。关于 versus ,将匹配单个垂直线条字符(例如 或 . 匹配新行 seqence -- , , 或 。这是一个很好的 stackoverflow.com/a/63922758/2943403 示范$sql
file_get_contents()
\v
\R
\v
\r
\n
\R
\r
\n
\r\n
\R
评论