匹配单词和单词的任何数量的第一个连续字符

时间:2012-05-16 02:10:34

标签: regex

是否有更简单的方法来编写以下正则表达式,特别是避免使用'?'的所有分组可选字符?

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

匹配以下内容:

  • 瓦特
  • WO

不应该匹配,仅作为示例:

  • WR
  • WD
  • WRR
  • wodr
  • wrdo
  • ORD
  • RD
  • ODR

在这个特殊情况下,这是一个非常简短的词,但你可以通过下一个例子看到事情如何变得非常丑陋。

正则表达式匹配垂直水平以及每个单词的任意数量的第一个连续字符:

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

我正在使用ruby,但我认为这个问题适用于任何使用正则表达式的语言,所以我会感谢任何语言的答案。不过对perl知之甚少......

我只发现了一个类似于我的问题,但无论如何都没有显示任何更好的解决方案,here is the link

3 个答案:

答案 0 :(得分:3)

您可以使用OR表达式简化它:

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

通过从输入文本中生成正则表达式来反向测试(伪代码):

"word" matches /input + ".*"/

答案 1 :(得分:1)

如果你以不同的方式做到了怎么办?例如(我不熟悉ruby,所以我将使用python):

s = "hor"

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

或者那些行

答案 2 :(得分: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(1))))))))????????)|·V(E(R(T( I(C(一(1))?)))))|???????\ $(1(0))$