3

PHPでMVCベースのサイトのルート処理クラスを書き直しており、URLのページ付け文字列を検出するための正規表現が必要です。ページネーションストリングは、3つの異なる部分で構成されています。

  • ページ番号の検出: /page/[NUMERIC]/
  • ページごとのアイテムの検出: /per_page/[NUMERIC]/
  • 注文検出: /sort/[ALMOST_ANY_CHARACTER]/[asc or desc]/

以前に開発された方法により、これらの3つの部分は任意の順序にすることができます。作業を続ける必要のある既存のリンクと、ページ付けを処理するために使用されるコードがいくつかあります(再書き込みの計画はまだありません)。したがって、常に一貫したURLを生成するようにページ付けコードを変更することはできません。

したがって、ページネーション構造のすべての可能な組み合わせを検出するために、正規表現パターンを作成する必要があります。各パーツを検出するための3つのパターンがあり、次のとおりです。

  • ページ番号の検出: (page/\d+)
  • ページごとのアイテムの検出: (per_page/\d+)
  • 注文検出: (sort/([a-zA-Z0-9\.\-_%=]+)/(asc|desc))

複雑な(とにかくこれは私にとって複雑です!)正規表現パターンを書くのは初めてですが、私が考えることができるのは、各URL構造に対して持っている3つのパターンを2つ組み合わせることだけです(例:/ pagenum / ordering / perpage /、 / pagenum / perpage / ordering /)および|の使用 'または'ステートメントとしての演算子。

これを行うためのより良い/より効率的な方法はありますか?

を使用して正規表現を実行していpreg_matchます。

4

3 に答える 3

4

先読みを使用できます。先読みが完全に一致した後、正規表現エンジンの位置は開始位置に戻ります(これが、*先読みと呼ばれる理由です。実際には、件名の文字列内の位置を進めたり、一致に何かを含めたりすることはありません)。目的の部分がいつ発生するかわからないため、文字列の先頭から3つの先読みをすべて開始し、キャプチャグループの前に.*任意の位置を許可します。

^(?=.*(page/\d+))(?=.*(per_page/\d+))(?=.*(sort/([a-zA-Z0-9\.\-_%=]+)/(asc|desc)))

キャプチャグループを少し切り替えることもできます。

preg_match(
  '~^(?=.*page/(\d+))(?=.*per_page/(\d+))(?=.*sort/([a-zA-Z0-9\.\-_%=]+)/(asc|desc))~', 
  $input,
  $match
);

これで、キャプチャは次のようになります。

$match[1] => page number
$match[2] => items per page
$match[3] => sort key
$match[4] => sort order

これらのいずれかをオプションにすることができる場合は、先読み全体をオプションにすることができます?

于 2012-12-15T18:51:45.097 に答える
1

先読みを使用することもできますが、何かが欠けていない限り、ここでは必要ないと思います。おそらく OR 演算子を使用できます。

(/(page/\d+)|/(per_page/\d+)|/(sort/([a-zA-Z0-9\.\-_%=]+)/(asc|desc)))+

ここでの外側のグループは、任意のグループ 1 またはグループ 2 またはグループ 3 の 1 つ以上のインスタンスを検索します。

その他の URL ルーティングのヒント:

この一般的なアプローチにより、実際には物事を少し単純化することもできます。Regex でルートのすべてのルールを定義するのではなく、最初に特定の種類のアクションを確認してからコードで処理します。最も単純なバージョン:

(/(page|per_page)/([\d+]))+

これで (外部グループの一致ごとに) 「アクション」と「値」を含む一致リストが得られます。アクションをオンにし、それに応じて値を処理します。

指定したとおりに並べ替えを処理するには (1 つではなく 2 つの値パラメーター)、別のレイヤーを追加します.. さらに興味深いものにするために、4 つ目のアクション を追加するとsearchします。一部のコンテンツのフィールド:

(/(page|per_page)/([\d+])|/(sort|search)/([^/]+)/([^/]+))+

繰り返しますが、一致リストを評価するときは、最初にアクションを確認します。どのアクションかによって、処理する連続する一致値の数がわかります。

お役に立てば幸いです。

于 2012-12-15T19:04:29.643 に答える
0

正規表現は使用しないでください。文字列を操作しているからといって、正規表現が適しているとは限りません。

パスを配列に分割し、パス/の各部分を配列の個々の要素として扱います。

$parts = explode( '/', $path );

if ( ( $parts[0] == 'page' ) && is_integer( $parts[1] ) ) {
....
于 2012-12-15T19:26:28.690 に答える