Reputation: 55
I'm trying to create a regex using javascript that will allow names like abc-def
but will not allow abc-
(hyphen is also the only nonalpha character allowed)
The name has to be a minimum of 2 characters. I started with
^[a-zA-Z-]{2,}$
, but it's not good enough so I'm trying something like this
^([A-Za-z]{2,})+(-[A-Za-z]+)*$
.
It can have more than one -
in a name but it should never start or finish with -
.
It's allowing names like xx-x
but not names like x-x
. I'd like to achieve that x-x
is also accepted but not x-
.
Thanks!
Upvotes: 4
Views: 5164
Reputation: 4302
Use this if you want to accept such as A---A
as well :
^(?!-|.*-$)[A-Za-z-]{2,}$
https://regex101.com/r/4UYd9l/4/
If you don't want to accept such as A---A
do this:
^(?!-|.*[-]{2,}.*|.*-$)[A-Za-z-]{2,}$
https://regex101.com/r/qH4Q0q/4/
So both will accept only word starting from two characters of the pattern [A-Za-z-]
and not start or end (?!-|.*-$)
(negative lookahead) with -
.
Upvotes: 1
Reputation: 4335
The problem is that the first assertion accepts 2 or more [A-Za-z]. You will need to modify it to accept one or more character:
^[A-Za-z]+((-[A-Za-z]{1,})+)?$
Edit: solved some commented issues
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('xggg-dfe'); // Logs true
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('x-d'); // Logs true
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('xggg-'); // Logs false
Edit 2: Edited to accept characters only
/^[A-Za-z]+((-[A-Za-z]{1,})+)?$/.test('abc'); // Logs true
Upvotes: 1
Reputation: 5510
^(?=[A-Za-z](?:-|[A-Za-z]))(?:(?:-|^)[A-Za-z]+)+$
Asserts that
If this matches
You can also use the I switch to make it case insensitive.
Upvotes: 0
Reputation: 18888
You can use a negative lookahead:
/(?!.*-$)^[a-z][a-z-]+$/i
Breakdown:
// Negative lookahead so that it can't end with a -
(?!.*-$)
// The actual string must begin with a letter a-z
[a-z]
// Any following strings can be a-z or -, there must be at least 1 of these
[a-z-]+
let regex = /(?!.*-$)^[a-z][a-z-]+$/i;
let test = [
'xx-x',
'x-x',
'x-x-x',
'x-',
'x-x-x-',
'-x',
'x'
];
test.forEach(string => {
console.log(string, ':', regex.test(string));
});
Upvotes: 3
Reputation: 22817
This option matches strings that begin and end with a letter and ensures two -
are not consecutive so a string like a--a
is invalid. To allow this case, see the Option 2.
^[a-z]+(?:-?[a-z]+)+$
^
Assert position at the start of the line[a-z]+
Match any lowercase ASCII letter one or more times (with i
flag this also matches uppercase variants)(?:-?[a-z]+)+
Match the following one or more times
-?
Optionally match -
[a-z]+
Match any ASCII letter (with i
flag)$
Assert position at the end of the linevar a = [
"aa","a-a","a-a-a","aa-aa-aa","aa-a", // valid
"aa-a-","a","a-","-a","a--a" // invalid
]
var r = /^[a-z]+(?:-?[a-z]+)+$/i
a.forEach(function(s) {
console.log(`${s}: ${r.test(s)}`)
})
If you want to match strings like a--a
then you can instead use the following regex:
^[a-z]+[a-z-]*[a-z]+$
var a = [
"aa","a-a","a-a-a","aa-aa-aa","aa-a","a--a", // valid
"aa-a-","a","a-","-a" // invalid
]
var r = /^[a-z]+[a-z-]*[a-z]+$/i
a.forEach(function(s) {
console.log(`${s}: ${r.test(s)}`)
})
Upvotes: 6
Reputation: 24812
I suggest the following :
^[a-zA-Z][a-zA-Z-]*[a-zA-Z]$
It validates :
-
)Upvotes: 0