0

半動的に生成された文字列を照合しようとしています。したがって、正しい形式であるかどうかを確認し、必要な情報をそこから抽出できます。私の問題は、正規表現をどれだけ把握しようとしても、私の一生の間、正規表現を理解できないことです。いわゆるジェネレーターの助けを借りても。

私が持っているのは、次のようないくつかの異なる文字列です。[@img:1234567890]および。[@user:1234567890]_ [@file:file_name-with.ext]このパススルーのような文字列は、フィルターを通過することを目的としているため、リンクやより読みやすい名前に置き換えることができます。しかし、私がそれらのいずれかのための正規表現を思い付くことができないかもしれないので、もう一度試してください。

私はフォーマットを探しています。[@word:]文字列から[、]、@、および単語を削除して、DBのクエリを適切に処理し、それに応じて処理できるようにします。正規表現ビットだけが私を妨げています。

4

3 に答える 3

1

ジェネレーターの意味がわかりません。私は常にオンラインマッチャーを使用して、テストケースが機能することを確認しています。@Virendraは、キャラクターから逃れるのを忘れた以外はほとんどそれを持っていました[]

/\[@(\w+):(.*)\]/

正規表現の区切り文字(この場合は「/」文字)で開始および終了する必要があります。

次に、文字の範囲を一致させるために正規表現で使用される「[]」をエスケープします。したがって、「[」。

次に、リテラルの「@」記号を照合します。

次に、この次の一致を保存して、後で使用できるようにし、で囲み()ます。

\wに一致しwordます。基本的に、スペース、句読点、または行の文字ではないすべての文字。

再びリテラルに一致し:ます。

マッチグループに2番目の部分も含めると便利な場合があり(.*)ます。これにより、任意の文字に何度でも一致し、保存しておくことができます。

次に、前に行ったように、クロージングを回避し]ます。

後でクエリで一致を使用したいように思われるので、preg_matchを使用して一致を配列に保存できます。

$pattern = '/\[@(\w+):(.*)\]/';
$subject = '[@user:1234567890]';
preg_match($pattern, $subject, $matches);
print_r($matches);

出力します

array(
    [0] => '[@user:1234567890]', // Full match
    [1] => 'user', // First match
    [2] => '1234567890' // Second match
)

私が見つけた特に役立つツールはtxt2reです

于 2012-10-07T00:25:14.193 に答える
1

これが私がすることです。

<pre>
<?php

    $subj = 'An image:[@img:1234567890], a user:[@user:1234567890] and a file:[@file:file_name-with.ext]';
    preg_match_all('~(?<match>\[@(?<type>[^:]+):(?<value>[^\]]+)\])~',$subj,$matches,PREG_SET_ORDER);
    foreach ($matches as &$arr) unset($arr[0],$arr[1],$arr[2],$arr[3]);
    print_r($matches);

?>
</pre>

これは出力します

Array
(
    [0] => Array
        (
            [match] => [@img:1234567890]
            [type] => img
            [value] => 1234567890
        )

    [1] => Array
        (
            [match] => [@user:1234567890]
            [type] => user
            [value] => 1234567890
        )

    [2] => Array
        (
            [match] => [@file:file_name-with.ext]
            [type] => file
            [value] => file_name-with.ext
        )

)

そして、これが私が関数をどのように使うかについての疑似バージョンですpreg_replace_callback()

function replace_shortcut($matches) {
    global $users;
    switch (strtolower($matches['type'])) {
        case 'img'  : return '<img src="images/img_'.$matches['value'].'jpg" />';
        case 'file' : return '<a href="files/'.$matches['value'].'" target="_blank">'.$matches['value'].'</a>';
        // add id of each user in array
        case 'user' : $users[] = (int) $matches['value']; return '%s';
        default : return $matches['match'];
    }
}

$users = array();
$replaceArr = array();

$subj = 'An image:[@img:1234567890], a user:[@user:1234567890] and a file:[@file:file_name-with.ext]';
// escape percentage signs to avoid complications in the vsprintf function call later
$subj = strtr($subj,array('%'=>'%%'));
$subj = preg_replace_callback('~(?<match>\[@(?<type>[^:]+):(?<value>[^\]]+)\])~',replace_shortcut,$subj);

if (!empty($users)) {

    // connect to DB and check users
    $query = "  SELECT `id`,`nick`,`date_deleted` IS NOT NULL AS 'deleted'
                FROM `users` WHERE `id` IN ('".implode("','",$users)."')";
    // query
    // ...
    // and catch results
    while ($row = $con->fetch_array()) {
        // position of this id in users array:
        $idx = array_search($row['id'],$users);
        $nick = htmlspecialchars($row['nick']);
        $replaceArr[$idx] = $row['deleted'] ?
            "<span class=\"user_deleted\">{$nick}</span>" :
            "<a href=\"users/{$row['id']}\">{$nick}</a>";
        // delete this key so that we can check id's not found later...
        unset($users[$idx]);
    }
    // in here:
    foreach ($users as $key => $value) {
        $replaceArr[$key] = '<span class="user_unknown">User'.$value.'</span>';
    }
    // replace each user reference marked with %s in $subj
    $subj = vsprintf($subj,$replaceArr);

} else {

    // remove extra percentage signs we added for vsprintf function
    $subj = preg_replace('~%{2}~','%',$subj);

}
unset($query,$row,$nick,$idx,$key,$value,$users,$replaceArr);

echo $subj;
于 2012-10-07T02:10:16.687 に答える
0

あなたはこのようなことを試すことができます:

/\[@(\w+):([^]]*)\]/

\[文字をエスケープし[ます(それ以外の場合は文字セットとして解釈されます)。\w「単語」の文字を[^]]*意味し、]文字以外の文字を意味します(タグの終わりを超えて一致することを避けるため.*)。ペアレンは、一致するさまざまなパーツをグループ化して、置換テキストを生成するために使用できるよう$1$2します。preg_replace

echo preg_replace('/\[@(\w+):([^]]*)\]/', '$1 $2', '[@link:abcdef]');

プリントlink abcdef

于 2012-10-07T00:25:32.690 に答える