web-dev-qa-db-ja.com

正規表現は、英数字、カンマ、ハイフン、アンダースコア、セミコロンのみを許可します

私はすでにいくつかの実用的なコードを持っていますが、それが機能するのであればなぜそれが機能するのか説明するのを手伝ってくれる人が必要です!

PHPを使用して、それがaz、AZ、0-9、コンマ、セミコロン、アンダースコア、ハイフン(最終的には、単一のユーザー名、またはユーザー名のカンマ/セミコロンで区切られたリスト)。

次の作品:

$data = preg_replace('/[^,;a-zA-Z0-9_-]/s', '', $data);

しかし、以下はそうではありません:

$data = preg_replace('/[^a-zA-Z0-9_-,;]/s', '', $data);

なぜこれが機能するのは、コンマとセミコロンが最初にあるときだけなのですか?それらを最後に置くと状況が崩れるようです(これは/ [^ a-zA-Z0-9 _-]/sに出会ったときに最初に試したものです。

余談ですが、私はtrailingセミコロン(複数)またはコンマ(複数)をトリミングするために次も使用しています。誰かがこれを行うためのより効率的でエレガントな方法を提案できるかもしれません。

if(preg_match('/;$/', $data))
{
    $data = rtrim($data, ';' );
}
if(preg_match('/,$/', $data))
{
    $data = rtrim($data, ',' );
}

助けてくれてありがとう:)

18
Robin

問題の原因はコンマやセミコロンではありません。ハイフンです。キャラクタークラスのパーツを見て、それらの意味を検討します。

0-9 # Anything from '0' to '9', meaning 0, 1, 2, ... 9
A-Z # Anything from 'A' to 'Z', meaning A, B, C, ... Z
_-, # Anything from '_' to ',', meaning...uh...hmmm.

_から,への明確な進展がないため、正規表現エンジンはこれをどのように処理すべきかわかりません。文字クラスでは、ハイフンを文字どおりに解釈したい場合は、クラスの先頭または末尾に配置する(またはバックスラッシュでエスケープする)必要があります。したがって、これらのいずれでも機能します。

[^,;a-zA-Z0-9_-]
[^-,;a-zA-Z0-9_]
[^a-zA-Z0-9_\-,;]

最後のトリミングに関しては、これをすべて1つの正規表現置換で行うことができます。

$data = preg_replace('/[^,;a-zA-Z0-9_-]|[,;]$/s', '', $data);
28
Justin Morgan

重要なのは、ハイフンの配置だと思います。ハイフン(リテラル)になるには、最初または最後に配置する必要があります。それ以外の場合は、範囲の定義に使用されます。

2
Devin Ceartas

ハイフンをエスケープして、次のように正規表現の任意の場所に配置できます\-

末尾のセミコロンとカンマについては、これを試してください/[,;]+$/カンマやセミコロンが多くても、末尾に一致する必要があります。

1
iDifferent