【问题标题】:Loop Preg_match until no more matches循环 Preg_match 直到不再匹配
【发布时间】:2015-09-04 16:49:40
【问题描述】:

我怎样才能 preg_match 直到找不到更多结果?

我正在使用 curl 登录一个页面,然后从那里删除帖子。

但要删除这些帖子,我需要 preg_match 内容并过滤 ID,如果在那里找到 ID,我的脚本运行删除命令。

所以,基本上:

$pattern = '/(?<=list_id=).*?(?=&cmd=edit)/s';
preg_match($pattern, $LoginResult, $id); //THIS PREG_MATCH IS WORKING, IT GETS THE FIRST RESULT OF THE PAGE (WHAT I NEED). BUT I NEED TO MAKE A LOOP TO THIS SCRIPT RUN OVER AND OVER UNTIL NOTHING MORE IS FOUND.
$idpagina = $id[0];

换句话说,它应该是这样的:

  • 如果 > preg_match 为 true > 运行删除命令。
  • 循环 If 直到 preg_match 为假。

通过这段代码,我可以找到 list_id=&cmd=edit 之间的所有内容。如果脚本在这两个字符串之间找到了一些东西,它需要执行一个 curl 来删除这个 ID:

//THIS IS WORKING
$paginadelete = "https://example/list/folder/0?list_id=".$idpagina."&cmd=delete&type=AD_DELETE";


    curl_setopt($login, CURLOPT_URL, $paginadelete);
    curl_setopt($login, CURLOPT_POST, 1);
    curl_setopt($login, CURLOPT_FOLLOWLOCATION, 1);
    $step1 = curl_exec($login);
    echo $step1;

这基本上做的是(或应该做的):

  1. 循环 preg_match,如果 preg_match 为真,则转到 #2
  2. 运行删除卷曲
  3. 返回 #1 直到在 preg_match 中找不到任何内容

但是这个脚本运行了 3 个 curl 进程:

  1. 登录
  2. 转到删除页面(上面这个)
  3. 确认删除

所以这个循环应该在第 2 步和第 3 步之间,直到找不到更多内容为止。

我的第 3 步(确认删除)是这个:

$url = curl_getinfo($login, CURLINFO_EFFECTIVE_URL);
$url = parse_url($url, PHP_URL_PATH);
$url = substr($url, 9);
$url = "http://example.com/cmd/act/".$url;

$post_data = array(
'1' => 'delete',
'2' => '1',
'3' => '2',
'4' => '10',
'5' => '',
'6' => 'continue',
);

//traverse array and prepare data for posting (key1=value1)
foreach ( $post_data as $key => $value) {
    $post_items[] = $key . '=' . $value;
}


//create the final string to be posted using implode()
$post_string = implode ('&', $post_items);


curl_setopt($login, CURLOPT_URL, $url);
curl_setopt($login, CURLOPT_POST, 1);
curl_setopt($login, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($login, CURLOPT_POSTFIELDS, $post_string);
$step2 = curl_exec($login);
//echo $step2;

////////////////////编辑

我在尝试:

if (preg_match('/(?<=list_id=).*?(?=&cmd=edit)/s', $LoginResult, $id)){
}
else {
}

但这仅适用于第一个结果。之后,脚本停止。我需要重新运行 if 直到 preg_match 为 false,然后以 else 结束。

我考虑过使用 DO 和 WHILE,但我不知道如何,也不知道它是否会起作用。

////////////////编辑2

我现在正在尝试使用 GOTO 直到获取错误并关闭连接

verification:
if (preg_match('/(?<=list_id=).*?(?=&cmd=edit)/s', $LoginResult, $id)){
[..........]
} else {
//close the connection
curl_close($login);      
}
goto verification;  

但似乎不起作用,哈哈。

【问题讨论】:

  • 为什么要使用正则表达式来解析查询字符串参数?为什么不使用像 parse_url()parse_str() 这样为您执行操作的内置 php 函数,或者甚至只访问 $_GET 变量?
  • 你试过使用preg_match_all吗?
  • @iam-decoder 因为此 URL 在输入中,而不是在标头中。
  • @PedroPinheiro 是的......但我认为这不是一个好主意,因为这个帖子页面将有很多页面......如果页面中存在 ID,我更喜欢每次脚本检查。
  • 您为什么不想同时删除所有帖子?额外的加载和花在动作上的时间有什么好处?

标签: php regex loops curl preg-match


【解决方案1】:

你的问题不清楚,但我猜你需要的是preg_match_all,即:

    preg_match_all('/((?<=list_id=).*?(?=&cmd=edit))/im', $html, $matches, PREG_PATTERN_ORDER);
    for ($i = 0; $i < count($matches[1]); $i++) {

       //here you can implement an if/else to check if the ID exist
        echo $matches[1][$i];
    }

http://php.net/manual/en/function.preg-match-all.php

【讨论】:

  • 我认为 Pedro Pinheiro 的回答更符合我的需要。在这种情况下 Preg_match_all 将无法正常工作。
【解决方案2】:

根据您的第一次编辑,您似乎想要实现以下目标:

while(preg_match('/(?<=list_id=).*?(?=&cmd=edit)/s', $LoginResult, $id)) {
    // do stuff
}
// do stuff after the preg_match is false

编辑

根据您对 cme​​ts 的描述,此代码可能会满足您的需求。

while(true) {
    $result = preg_match('/(?<=list_id=).*?(?=&cmd=edit)/s', $LoginResult, $id);
    if($result) {
        // Run Delete Curl
    } else {
        curl_close($login);
        break;
    }
}

【讨论】:

  • 我会测试这个...我只是在控制面板中添加新帖子,我会尝试删除。我尽快在这里提供反馈:D 谢谢。
  • 嗯...脚本继续运行,它只删除第一个结果。是的......页面继续运行......
  • //do stuff 部分中,您需要指定一些条件来中断循环或更改$LoginResult 可能使用preg_replace
  • 抱歉回复晚了。在 '// 在 preg_match 为 false 之后做的事情' 我关闭了 curl 连接 'curl_close($login);'即使它不起作用....有什么想法吗?
  • @Diego,我更新了答案,看看对你有没有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 2021-07-20
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多