0

次の正規表現を書く簡単な方法はありますか?具体的には、「?」ですべてのグループ化を避けます。オプションの文字?

/^w(o(r(d)?)?)?$/

次のように一致する必要があります。

  • w
  • wor

単なる例として、一致してはなりません。

  • wr
  • wd
  • ウー
  • wrr
  • wodr
  • wrdo
  • オード
  • rd
  • odr

この特定のケースでは、それは非常に短い言葉ですが、この次の例で、物事が非常に速く醜くなる可能性があることがわかります。

垂直または水平、および各単語の最初の連続文字の任意の量に一致する正規表現:

/^h(o(r(i(z(o(n(t(a(l)?)?)?)?)?)?)?)?)?|v(e(r(t(i(c(a(l)?)?)?)?)?)?)?)$/

私はルビーを使っていますが、この質問は正規表現を使用するすべての言語に当てはまると思いますので、どの言語の回答にも感謝します。しかし、perlについてはあまり知りません...

私は私のような質問を1つだけ見つけましたが、とにかく、これ以上の解決策は示されていません。ここにリンクがあります。

4

3 に答える 3

3

OR次の式で簡略化できます。

/^(w|wo|wor|word)$/

または、入力テキスト(擬似コード)から正規表現を作成してテストを逆にします。

"word" matches /input + ".*"/
于 2012-05-16T02:41:54.173 に答える
1

別の方法で行った場合はどうなりますか?たとえば(私はルビーに精通していないので、Pythonを使用します):

s = "hor"

if "horizontal".startswith (s):
    h = True
if "vertical".startswith (s):
    v = True

またはそれらの線に沿った何か

于 2012-05-16T02:37:08.517 に答える
0

醜くて読みにくいですが、単語ごとに正規表現を作成する関数を作成します。たとえば、PHPの場合、次のように定式化します。

function rx_from_word($word='',$escapeNeeded=true) {
    $rx = ''; $i = strlen($word);
    while (--$i > -1) {
        if ($escapeNeeded && strpos('|/{}[]().*\\+^$',$word{$i}) !== false) $char = '\\'.$word{$i};
        // I'm not sure if I missed any special character above.
        else $char = $word{$i};
        if ($i > 0) $rx = '(' . $char . $rx . ')?';
        else $rx = $char . $rx;
    }
    return $rx;
}

function rx_from_words($words=array(),$matchFull=false) {
    $rx = $matchFull ? '^' : '';
    foreach ($words as $word) $rx .= rx_from_word($word) . '|';
    return substr($rx,0,-1) . ($matchFull ? '$' : '');
}

$words = array('horizontal','vertical','$10');
$rx = rx_from_words($words,1);
echo "<pre>$rx</pre>";

出力します

^ h(o(r(i(z(o(n(t(a(l)?)?)?)?)?)?)?)?)?| v(e(r(t(i(c (a(l)?)?)?)?)?)?)?| \ $(1(0)?)?$

于 2012-05-16T02:53:03.443 に答える