2016-12-08 10 views
0

大括弧で囲まれた日時を取得する方法が必要です。だから、次の文字列のために:preg_matchを使ってPHPで大括弧で囲まれた日付と時刻を取得する

$str= '10.1.1.107 - - [27/Oct/2016:06:40:58 +0000] "GET /advise/asi/3571502300/sky/2/con/113 HTTP/1.1"'; 

私は次のようにadviseconを取得するためにトリングだ:

preg_match("/advise\/([a-zA-Z0-9\-]+)\/sky\/2\/.*con\/([0-9]+)/", $str, $matches); 

関数は次のよう$matchesを返します。

Array ( 
[0] => 
    array(2) { 
    [0]=> 
    "3571502300" 
    [1]=> 
    "113" 
} 
) 

それから私はしたいです大括弧で囲まれた日付と時刻を取得するには、次の正規表現を使用します。

/\[([0[1-9]|[1-2][0-9]|3[0-1]\/Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec\/20\d\d:\d{2}:\d{2}:\d{2}\+0000)]\]\/advise\/([a-zA-Z0-9\-]+)\/sky\/2\/.* con\/([0-9]+)/ 

しかし、それは私の正規表現が間違っ

ですcaptures nothing

私はこのような配列を得る:

Array ( 
[0] => 
    array(3) { 
    [0]=> 
    27/Oct/2016:06:40:58 +0000 
    [1]=> 
    "3571502300" 
    [2]=> 
    "113" 
} 
) 

答えて

1
$re = '/\[(?P<dt>\d\d\/[A-Z][a-z]{2}\/\d{4}(?:\:\d\d){3} \+\d{4})\] ' . 
    '"[A-Z]{3,4} \/advise\/asi\/(?P<asi>\d+)\/sky\/\d+\/con\/(?P<con>\d+)/'; 

preg_match($re, $str, $m); 
var_dump($m['dt'], $m['asi'], $m['con']); 
// or, if your prefer numeric indices: 
//var_dump($m[1], $m[2], $m[3]); 

出力

string(26) "27/Oct/2016:06:40:58 +0000" 
string(10) "3571502300" 
string(3) "113" 

説明

値がフォームでsubpatterns命名使用して撮影されました:

ここで、nameはmatches配列のキー名です。

(?:\:\d\d){3}は、年末以降の部分ではnon-capturing groupです(特に、:06:40:58)。

残りはシンプルです。角括弧上記のサンプルコードではバックスラッシュでエスケープされていることを、あなたの正規表現で

エラー

注:\[\]、正規表現で、彼らはset of charactersを意味するので。角括弧をエスケープしなかったので、その間の文字は一連の文字として解釈されます。

部分sky\/2\/.* con\/は、元の文字列にcon/の前にスペースが含まれていないため、間違っています。

タイムゾーンオフセット(\+0000)をハードコードしました。ホスト上でタイムゾーンが変更されることはありませんが、それでも可能です。したがって、より遺伝的な形で書く方が良いです。 \+\d{4}

1

代替バージョンをグループ化する必要があります。そうでなければ、orは正規表現全体に影響します。例えば

^12|34$ 

12又は34しかし

^1(2|3)4$ 

124又は134できます。

文字列にもタイムゾーンオフセットと秒の間にスペースがあるため、文字通り追加する必要があります(または\hメタ文字を使用できます)。

デモ:https://regex101.com/r/ykuAP9/3

ので、正規表現は次のようになります。

~\[((?:[0[1-9]|[1-2][0-9]|3[0-1])/(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/20\d\d:\d{2}:\d{2}:\d{2} \+0000)\]~ 
+0

あなたが言及した日時書式が正しいです –

関連する問題