1. ホーム
  2. php

php regular application: exception Delimiter must not be alphanumeric or backslash.

2022-03-02 12:17:38
<パス

エヘン、3年以上phpを使わず、いろんなことを忘れて、フルスタックのために、今少しづつ、かつて歩いた穴を記録するためにブログを書きながら、今穴を歩いています。

問題が発生するコードは以下の通りです。

$content = request("http://pp.163.com/pp/searchpic/?q=%B7%E7%BE%B0");
$details = matchDetailInList($content);
var_dump($details);

function request($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//return the string instead of outputting it directly
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // page 301, 302 bounce occurred

    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

/**
 * Match the address of the detail page in the list page
 */
function matchDetailInList($content) {
    // Note that there is a problem with this in php
    $ruleMatchDetailInList = "http://*[^\"]*\.html[^\"]*";
    preg_match_all($ruleMatchDetailInList,$content,$result);  
    return $result;  
}

このコードは以下の例外を除いて実行されます。

Warning: preg_match_all(): Delimiter must not be alphanumeric or backslash in D:\wamp\www\curl\curlTest.php on line 29


通常のテストツールでは全く問題ないのに、phpでは一体何が問題なのでしょうか?

Warningのヒントを見ると、デリミタが英数字やバックスラッシュではダメだと言っていることがわかります。

デリミタって何?eregではなくpregにあり、正規表現の始まりと終わりを区切るものです。では、前後にデリミタを付けてみましょう。英数字やバックスラッシュは使えないと書いてあるから、#、~、/などの他の文字を使おう(もちろん、前と後ろはペアで出現させなければならない)。

最初に#または~に切り替えます。

function matchDetailInList($content) {
    $ruleMatchDetailInList = "~http://*[^\"]*\.html[^\"]*~";
    preg_match_all($ruleMatchDetailInList,$content,$result);  
    return $result;  
}

案の定、以下のように動作しました。

ただし、/slashに切り替えた場合

function matchDetailInList($content) {
    $ruleMatchDetailInList = "/http://*[^\"]*\.html[^\"]*/";
    preg_match_all($ruleMatchDetailInList,$content,$result);  
    return $result;  
}

別のエラーが報告されました。

Warning: preg_match_all(): Unknown modifier '/' in D:\wamp\www\curl\curlTest.php on line 29


次のようなイメージです。

未知の修飾子 '/'? それとも規則性に問題があるのか!
これは、ルール自体に「/」があるためです。"http://" の2つの「//」を見てください。区切り文字と衝突しているので、バックスラッシュを追加して、それをエスケープしてから試してください。

function matchDetailInList($content) {
    $ruleMatchDetailInList = "/http:\/\/*[^\"]*\.html[^\"]*/";
    preg_match_all($ruleMatchDetailInList,$content,$result);  
    return $result;  
}

実行する

確かに、もう問題はありません
ですから、デリミタを使うときは、レギュラーのスラッシュとの衝突を避けるために、スラッシュ/を使わないようにすることをお勧めします。

まとめますと
1. phpで、デリミタを持つには
2. 区切り文字にスラッシュ / を使用せず、# または ~ を使用するようにしてください。