Rahul
Rahul

Reputation: 5823

Regex to verify first and last character

I need to verify in php that a string should not start or end with a hyphen (-). The allowed characters are a-z, A-Z, 0-9 and a hyphen anywhere in the middle of the string.

My this regex

/^[a-zA-Z0-9-]+$/

Verifies the occurrence of allowed character expect the condition that the string should not start or end with the hyphen. How do I achieve this? I new to regex.

Upvotes: 0

Views: 14648

Answers (6)

stema
stema

Reputation: 93026

Use negative look ahead and look behind to achieve this

^(?!-)[a-zA-Z0-9-]+(?<!-)$

See it here on Regexr

^(?!-) is a negative look ahead assertion, ensures that it does not start with a dash

(?<!-)$ is a negative look behind assertion, ensures that it does not end with a dash

The advantage of the lookarounds is that they do not match a character, but just defining an assertion, that means your string can also have a length of 1, where the solution with explicitly requiring a non dash as first and last character makes a min length of 2.

Btw. a-zA-Z0-9_ is a predefined class \w so if you also want to allow the underscore you can change to:

^(?!-)[\w-]+(?<!-)$

Upvotes: 4

Michael
Michael

Reputation: 12806

This should be what you need.

/^[a-z0-9]+([a-z0-9-]+[a-z0-9])?$/iD

Notice the D modifier. Without it the expression would match a string that ends in a new line. See here: http://blog.5ubliminal.com/posts/surprises-of-php-regexp-the-d-modifier/. Also, I've used the i modifier to not have to use [a-zA-Z0-9]. Keeps the expression shorter.

Here's a couple of examples. As the input string ends in a new-line, it should fail, but without the D modifier, even with the $ anchor, it passes:

// Outputs: int(1)
var_dump(preg_match('/^[a-z0-9]+([a-z0-9-]+[a-z0-9])?$/i', "aBc-d\n"));

// Outputs: int(0)
var_dump(preg_match('/^[a-z0-9]+([a-z0-9-]+[a-z0-9])?$/iD', "aBc-d\n"));

Upvotes: 4

Andreas Wong
Andreas Wong

Reputation: 60584

This isn't a regular expression per-se but works according to your requirements:

if(
   ctype_alnum($str[0]) && 
   ctype_alnum($str[strlen($str)-1]) && 
   strpos(substr($str, 1, strlen($str-1)), '-') !== false
) {
   echo 'a match';
}

Upvotes: 0

Berry Langerak
Berry Langerak

Reputation: 18859

Verifies the occurrence of allowed character expect the condition that the string should not start or end with the hyphen. How do I achieve this? I new to regex.

Put simply: ~^[^-][a-z0-9-]+[^-]$~ should match. It says the first character can not be a -, then it says the middle part can only contain [a-z0-9-], and then it says the last character can't be a '-'. That said, you can also do this with substr, I don't think you actually need a regular expression.

With substr:

<?php
$valid = ((substr($str, 0, 1) != '-') && (substr($str, -1) != '-'));

EDIT: Didn't read the alphanumeric plus hyphen part, included it in the regex.

Upvotes: 1

M Lamb
M Lamb

Reputation: 199

Try this:

/^[a-zA-Z0-9_]+[a-zA-Z0-9_-]*[a-zA-Z0-9_]+$/

"One or one of anything except the hyphen, then any number of anything including hyphen, then one or more anything except the hyphen".

EDIT: This will fail if the string is one character long. Sorry about that. But you get the idea... Split it into sub-regex's.

Upvotes: 1

Ramzi Khahil
Ramzi Khahil

Reputation: 5072

Use the substr method. something like:

if ((substr($str, 0, 1) != '-') && (substr($str, strlen($str)) != '-')){

It may also has a function similar to charAt in javascript but I don't remember it right now. (That will get you a more readable code)

Upvotes: 0

Related Questions