Take the 2-minute tour ×

Is there a simpler way to write the following regular expression, specifically avoiding all the groupings with the '?' optional character?


It should match the following:

  • w
  • wo
  • wor
  • word

and should not match, as mere examples:

  • wr
  • wd
  • woo
  • wrr
  • wodr
  • wrdo
  • ord
  • rd
  • odr

In this particular case its a very short word but you can see by this next example how things can become ugly very fast.

Regex to match vertical or horizontal and any amount of first sequential characters of each word:


I'm using ruby but I think this question applies to any language that makes use of regular expressions, so I'll thank answers in any language. Don't know much about perl, though...

I only found one question similar to mine but doesn't show any better solution, anyway, here is the link.

share|improve this question
What programming language? Probably easier to just do a string comparison than a regex. Pseudocode: substring(word, 0, length(partial_word)) == partial_word –  Michael Berkowski May 16 '12 at 2:17
This classic problem is best solved by reversing the string and the pattern. Using Perl syntax for interpolating a variable into a pattern, that’s "HORIZONTAL" =~ /^$word/i, which will match "h", "ho", "hor", etc, but not "horripilate" and such. –  tchrist May 16 '12 at 3:52

3 Answers 3

up vote 3 down vote accepted

You could simplify it with an OR expression:


or reverse the test by making a regex from the input text (in pseudo code):

"word" matches /input + ".*"/
share|improve this answer
+1 for reversing the test. That is clever. Unfortunately it makes it difficult to trawl through a large file looking for words so it is far less useful than a normal regex. –  thagorn May 16 '12 at 2:45
+1V for reversing the test. I was actually hoping for some recursive syntax available from regex themselves but the reversing concept is really worth having when dealing with cases like this. Thanks –  jasoares May 16 '12 at 13:03

What if you did it a different way? For example (I'm not familiar with ruby, so I'll use python):

s = "hor"

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

Or something along those lines

share|improve this answer
+1 for reverse as in the answer of Bohemian –  jasoares May 16 '12 at 13:05

Although ugly and harder to read, I would create a function to create the regex for each word. If it were PHP, for example, I would formulize it like the following:

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>";

which would output


share|improve this answer

Your Answer


