2

私の検索パネルでは、次のような文字列をフィルタリングする必要があります。

'4dan-7kyu' or '4dan - 7kyu' or '10kyu' or '10 kyu' or '2dan' or '2 dan' or  '4-7'  or '4 - 7'  or  '10'  

許可されるのは次の場合のみです。

  1. からの番号1-10;
  2. 大文字と小文字が区別されない単語には、次のものがdan含まkyuданますкью
  3. ダッシュ (文字列の先頭に 1 つ以下 AND なし、never-10kyuまたは never -10);
  4. スペース (文字列の先頭には 1 回まで);

私はこのようなことを考えていましたが、私にとっては完全には機能しませんでした:

/([1-9]|10)\s-\s|dan|kyu|дан|кью/i

そのような正規表現を絞り込む正しい方法は何ですか?

編集1:

  1. スペース (文字列の先頭には 1 回まで)
    無効な例:4dan___-___7kyuまたは_4dan_-_7kyu
    有効な例: 4dan-7kyuand 4dan - 7kyuand and 4 dan - 7kyuand4 dan - 7 kyu

編集2:

その他の無効な例: 12dan-7kyuまたは12dan-11kyu

4

4 に答える 4

4

あなたの要件をよく理解していれば、次の正規表現を試すことができます。

'((?!(?:[^'\s]*\s[^'\s]*){2,}'|(?:[^'-]*-[^'-]*){2,}')(?:(?:[1-9]|10)\s?-?(?:dan|kyu|дан|кью)?-?)*)'

regex101 のデモを見る

先頭の否定先読みは、文字列に 2 つ以上のスペースやダッシュがないことを確認します。

次に、一致するグループで可能な組み合わせを取得し、すべてをキャプチャして、引用符なしで文字列を取得します。先読みと後読みを使用して、キャプチャを回避することもできます。

(?<=')(?!(?:[^'\s]*\s[^'\s]*){2,}'|(?:[^'-]*-[^'-]*){2,}')(?:(?:[1-9]|10)\s?-?(?:dan|kyu|дан|кью)?-?)*(?=')

編集:

更新によると、おそらくこの正規表現を試すことができます:

^(?:(?:[1-9]|10)(?![0-9])) ?(?:(?:dan|kyu|дан|кью) ?)?(?:-? ?(?:(?:[1-9]|10)(?![0-9])) ?(?:(?:dan|kyu|дан|кью) ?)?)*$
于 2013-08-28T08:02:15.200 に答える
4
\b(?<!-)(10|[1-9])(?: ?(dan|kyu|дан|кью))?(?: ?- ?(10|[1-9])(?: ?(dan|kyu|дан|кью))?)?\b

キャプチャを参照してください。

上記の正規表現を作成しましたが、あまり読みにくいので、コードに入れると、「次の人」にとってより理解しやすくなります(preg-replaceタグとして持っていることに気付いたので、PHPを想定しています):

$numbers = '(10|[1-9])';
$words = '(dan|kyu|дан|кью)';
$seperators = ' ?- ?';

$regex =
  '~\b'.
    '(?<!-)'.
    $numbers.
    '(?:'.
      ' ?'.
      $words.
    ')?'.
    '(?:'.
      $seperators.
      $numbers.
      '(?:'.
        ' ?'.
        $words.
      ')?'.
    ')?'.
  '\b~';

$string = "'12dan-7kyu' or '12dan-11kyu' or '_4dan_-_7kyu' or '4 dan - 7kyu' or '4 dan - 7 kyu' or '4dan___-___7kyu' or '4dan-7kyu' or '4dan - 7kyu' or '10kyu' or '10 kyu' or '2dan' or '2 dan' or  '4-7'  or '4 - 7'  or  '10'  ";

preg_match_all($regex, $string, $out, PREG_SET_ORDER);

実行してください。

于 2013-08-28T09:01:57.557 に答える
4

私はそれだと思います:

/(^([1-9]|10)\s*$)
|
(^([1-9]|10)\s?-\s?([1-9]|10)\s*$)
|
(^([1-9]|10)\s?(dan|kyu|дан|кью)\s*$)
|
(^([1-9]|10)\s?(dan|kyu|дан|кью)\s?-\s?([1-9]|10)\s?(dan|kyu|дан|кью)\s*$)/ixu

PHPのサンプルは次のとおりです。

$rgData   = ['12', '20dan', ' 1kyu - 4kyu   ', '1kyu - 4kyu  ', 
             '1 kyu - 4 kyu', '1 kyu-4 kyu','4dan-7kyu', '4dan - 7kyu', 
             '10kyu', '10 kyu', '2dan', '2 dan', '4-7', '4 - 7', '10'];
$sPattern = '/(^([1-9]|10)\s*$)
             |
             (^([1-9]|10)\s?-\s?([1-9]|10)\s*$)
             |
             (^([1-9]|10)\s?(dan|kyu|дан|кью)\s*$)
             |
             (^([1-9]|10)\s?(dan|kyu|дан|кью)\s?-\s?([1-9]|10)\s?(dan|kyu|дан|кью)\s*$)/ixu';
var_dump(array_filter($rgData, function($sItem) use ($sPattern)
{
   return preg_match($sPattern, $sItem, $rgMatches);
}));//first 3 not matched

PS 武道の同僚への挨拶!

于 2013-08-28T07:55:30.870 に答える
0

次のように RegEx を少し変更するだけです。

/((10|[1-9])(\s?-?\s?)(dan|kyu|дан|кью)?(\s?-?\s?)(([10|[1-9])(\s?-?\s?)(dan|kyu|дан|кью)?)?)/i

これは元の正規表現を使用しますが、数字と段または九の間の空白とハイフンをオプションにし、オプションの空白とハイフンをさらに多くして、オプションで繰り返します。

また、[1-9]|10 の部分を入れ替えて、1 をつかんで先に進まないようにしました。

于 2013-08-28T08:03:40.447 に答える