Run
Run

Reputation: 57286

PHP preg_match with regular expression: only single hyphens and spaces between words

How can I allow single hyphens and single spaces only within words but not at the beginning or at the end of the words?

if(!preg_match('/^[a-zA-Z0-9\-\s]+$/', $pg_tag))
    {
        $error = true;
        echo '<error elementid="pg_tag" message="TAGS - only alphanumbers and hyphens are allowed."/>';
    }

I don't want to accept these inputs below

---stack---over---flow---
stack-over-flow- stack-over-flow2
   stack    over    flow

but only these are acceptable,

stack-over-flow stack-over-flow2 stack-over-flow3
stack over flow
stacoverflow

Thanks.

Upvotes: 1

Views: 3758

Answers (3)

Vineet Jain
Vineet Jain

Reputation: 21

To accept character or digit with space in between them. In case of only space it fails the test or do not accept only.

This Regular expression accept string like "Home Work" but failed with " ".

var pattern = /^(?=.*\S)[.+a-z0-9A-Z-.#:!*$^_|?` ]+$/;
     return pattern.test(value);

This returns true if string is accepted.

Upvotes: 1

enobrev
enobrev

Reputation: 22541

$aWords = array(
    'a',
    '---stack---over---flow---',
    '   stack    over    flow',
    'stack-over-flow',
    'stack over flow',
    'stacoverflow'
);

foreach($aWords as $sWord) {
    if (preg_match('/^(\w+([\s-]\w+)?)+$/', $sWord)) {
        echo 'pass: ' . $sWord . "\n";
    } else {
        echo 'fail: ' . $sWord . "\n";
    }
}

And the output:

pass: a
fail: ---stack---over---flow---
fail:    stack    over    flow
pass: stack-over-flow
pass: stack over flow
pass: stacoverflow

A breakdown of the Regex:

^             # Match from the very beginning of the string
(             # Start Group
    \w+       # At least one "word" character
    (         # Start Subgroup
       [\s-]  # A single space or a dash
       \w+    # At least one "word" character
    )?        # End Subgroup is optional
)+            # End group - allow it multiple times
$             # Match until the very end of the string

Upvotes: 5

Felix Kling
Felix Kling

Reputation: 817208

With respect to the comments: Another idea is to "normalize" the input, i.e. reducing all consecutive spaces and dashes to one and removing them from the beginning and end:

$pg_tag = preg_replace(array('/\s+/', '/-+/'), 
                       array(' ', '-'), 
                       trim($pg_tag, ' -'));

Reference: preg_replace, trim

Upvotes: 1

Related Questions