次の正規表現を書きました
$pattern = "~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s-']+~";
部分文字列を次のように一致させるために2.bon jovi - it's my life
問題は、認識される唯一の部分です - bon jovi
" - " または " ' " は、この正規表現によって認識されません。
新しい正規表現を取得するよりも、作成した正規表現の何が問題なのかを知りたいです。
あなたの正規表現は次のとおりです。
~ // delimiter
\d+ // 1 or more numbers
[.] // a period
[\s]* // 0 or more whitespace characters
[A-Z]{1} // 1 upper case letter
[A-Za-z0-9\s-\']+ // 1 or more characters, from the character class
~ //delimiter
それを文字列「2.bon jovi」と比較すると、次のようになります。
~ //
\d+ // "2"
[.] // "."
[\s]* // ""
[A-Z]{1} // <- NO MATCH
[A-Za-z0-9\s-\']+ //
~ //
「bon」は大文字で始まらないため一致しません[A-Z]{1}
正規表現をクリーンアップするためにできる簡単なことがいくつかあります
{1}
でください。存在しないのと同じです上記を既存の正規表現に適用すると、次のようになります。
$pattern = "~\d+\.\s*[A-Z][A-Za-z0-9\s-']+~";
これは少し読みやすいです。
$pattern = "~\d+\..*~";
$string = "2.bon jovi - it's my life";
preg_match($pattern, $string, $match);
print_r($match);
出力: 配列 ( [0] => 2.bon jovi - それは私の人生です )
したがって、この正規表現を理解する方法は次のとおりです。
\d+ // Match any digit, 1 or more times
[.] // Match a dot
[\s]* // Match 0 or more whitespace characters
[A-Z]{1} // Match characters between an UPPERCASE A-Z Range 1 time
[A-Za-z0-9\s-']+ // Match characters between A-Z, a-z, 0-9, whitespace, dashe and apostrophe
そのため、'bon jovi' は小文字であり、大文字のみを探しているため、すぐには一致しない可能性があります。「bon jovi」にはスペースも含まれているため、正規表現のその部分を変更して小文字と空白を許可すると役立つ場合があるため、次のようになります。
$pattern = "~\d+[.][\s]*[A-Za-z\s]{1}[A-Za-z0-9\s-']+~";
注: これを RegExr ( http://gskinner.com/RegExr/ ) ですばやくテストしたところ、文字列とうまく一致するように見えました。
それを処理するためのより良い正規表現は...
$pattern = "~\d+\.\s*[\pL\pP\s]+~";
.
これは、数字の後に が続き、その後にオプションの空白が続き、その後に 1 つ以上の Unicode 文字、空白、または句読点が続くものと一致します。
正規表現では、ピリオド文字 (に変更可能\.
) の後に、0 個以上の空白文字があり、その後に 1つの大文字が続く必要があることが示されています。文字列に大文字が含まれていません。
次に、-
を一致させたい場合は最後に配置する必要があります。したがって、正規表現を this: に変更すると、~\d+[.][\s]*[A-Z]{1}[A-Za-z0-9\s'-]+~
so: のようなものと一致します2.Bon jovi - it's my life
。
一方、これを this: に変更して、~\d+[.][\s]*[A-Za-z0-9\s'-]+~
so: のようなものに一致させることができます2.bon jovi - it's my life
。
編集: Marko D と aleation のコメントに従って修正されました。
[A-Z]{1}
サブパターンには大文字が 1 つ必要なため、"2.bon jovi - it's my life"
一致しません。
-
また、文字クラスでエスケープする[A-Za-z0-9\s-']
か、先頭または末尾に配置する必要があります。そうしないと、範囲が指定されます。
"~\d+\.[A-Za-z0-9\s'-]+~"
コメントで指摘されているように、実際には-
、正規表現の文字クラスでエスケープする必要はありません。これは、たまたま\s
、範囲の一部にならないメタ文字を前に付けたためです。通常、文字クラスにリテラルを一致させたい場合-
は、それをエスケープするか、上記のように配置する必要があります。