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.
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"));
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-]+(?<!-)$
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.
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.
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)
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';
}
Related
I have been looking around and googling about regex and I came up with this to make sure some variable has letters in it (and nothing else).
/^[a-zA-Z]*$/
In my mind ^ denotes the start of the string, the token [a-zA-Z] should in my mind make sure only letters are allowed. The star should match everything in the token, and the $-sign denotes the end of the string I'm trying to match.
But it doesn't work, when I try it on regexr it doesn't work sadly. What's the correct way to do it then? I would also like to allow hyphen and spaces, but figured just starting with letters are good enough to start with and expand.
Short answer : this is what you are looking for.
/^[a-zA-Z]+$/
The star * quantifier means "zero or more", meaning your regexp will match everytime even with an empty string as subject. You need the + quantifier instead (meaning "one or more") to achieve what you need.
If you also want to match at least one character which could also be a whitespace or a hyphen you could add those to your character class ^[A-Za-z -]+$ using the plus + sign for the repetition.
If you want to use preg_match to match at least one character which can contain an upper or lowercase character, you could shorten your pattern to ^[a-z]+$ and use the i modifier to make the regex case insensitive. To also match a hyphen and a whitespace, this could look like ^[a-z -]+$
For example:
$strings = [
"TeSt",
"Te s-t",
"",
"Te4St"
];
foreach ($strings as $string) {
if(preg_match('#^[a-z -]+$#i', $string, $matches)){
echo $matches[0] . PHP_EOL;
}
}
That would result in:
TeSt
Te s-t
Output php
This is what I'm trying to do,
$line = "dsfsdf";
if (!preg_match('/^(?=.{1,30}$)[a-zA-Z0-9\-\_]*$^/', $line))
{
echo 'No Match found';
}
else
{
echo 'Match found';
}
The requirement is below,
it can have characters
it can have numbers
As special character, it can have only hyphen (-) and underscore (_) characters in it
I'm not so good at regex part. Can someone guide me how to achieve it with a simple explanation?
You must remove ^ (start of string anchor) at the end. Also, you may replace [a-zA-Z0-9_] with \w, as without any modifiers, they are equal.
The (?=.{1,30}$) lookahead makes the regex engine only match strings with 1 to 30 characters. You may remove the lookahead and just apply the limiting quantifier to your character class.
You may use
'/^[\w-]{1,30}$/'
If you prefer a more verbose way use
'/^[a-zA-Z0-9_-]{1,30}$/'
See the PHP demo.
Both mean:
^ - start of string
[\w-]{1,30} - 1 to 30 letters/digits/underscores/- symbols
$ - end of string. NOTE that to match at the very end of the string, you need to use a D modifier, or replace $ with \z anchor (i.e. use '/^[\w-]{1,30}$/D' or '/^[\w-]{1,30}\z/' then).
Hi very interesting Regex Expression, i tried a lot of time,but some difficulties in it.
Regex rule:
user can use following characters all small([a-z]), all capital([A-Z]), numbers([0-9]) and the follownig symbols
!~*:;<>+#-£$&_?(){}[] and one space. All characers are in any order,
but restiriction are following:
input can not start with digit.
user can use zero or one white space any where in the input, but input can not start and end with white space.
input must contains at least one special following character!~*:;<>+#-£$&_?(){}[] in any order.
input length is in between 6-15.
Question: Regular expression which fullfills the above requirment. i have spent many of hours on it.but make the following Regex expression.
Regex='/^([a-zA-Z]|!|\~|*|\:|\;|\<|>|+|#|-|\£|\$|\&|_|\?|{|}|[|]|(|)){1,20}(\s){0,1}([a-zA-Z]|!|\~|*|\:|\;|\<|>|+|#|-|\d|\£|\$|\&|_|\?|{|}|[|]|(|)){1,20}(!|\~|*|\:|\;|\<|>|+|#|-|\£|\$|\&|_|\?|{|}|[|]|(|)){1,}$/i';
it fullfills all rule but not rule no.4.
complete regex which fullfills the above rules will be appreciated.
Some hints before getting to the solution.
You use the modifier i, means "case independent" matching. So no a-zA-Z needed just use a-z or A-Z.
From your list of characters [a-zA-Z]|!|\~|*|\:|\;|\<|>|+|#|-|\£|\$|\&|_|\?|{|}|[|]|(|)
There are some characters that needs escaping, since they are special in regex.
Skip the alternation and put all characters in the char class (you can also spare the escaping then)
To enforce some of your rules you need lookahead assertions
So your regex (for php) can look like:
^(?![\d ])(?![^ ]*[ ][^ ]*[ ])(?=.*[!~*:;<>+#\-£$&_?{}\[\]()])[a-z\d!~*:;<>+#\-£$&_?{}\[\]() ]{6,15}(?<![ ])$
If you need the regex for JavaScript, you can not use the lookbehind assertion. You can replace it also by a lookahead:
^(?![\d ])(?!.* $)(?![^ ]*[ ][^ ]*[ ])(?=.*[!~*:;<>+#\-£$&_?{}\[\]()])[a-z\d!~*:;<>+#\-£$&_?{}\[\]() ]{6,15}$
See it here on Regexr (Note. I have used there [^ \r]) just because I need multiline for testing)
The regex explained:
[a-z\d!~*:;<>+#\-£$&_?{}\[\]() ]{6,15} matches all characters you want to allow, in the required length.
(?![\d ]) negative lookahead assertion, that ensures the string does not start with a digit or a space.
(?![^ ]*[ ][^ ]*[ ]) negative lookahead assertion, that ensures the string does not have more than one space
(?=.*[!~*:;<>+#\-£$&_?{}\[\]()]) positive lookahead assertion, that ensures the string does have one of your special symbols
(?<![ ])$ negative lookbehind assertion, that ensures the string does not end with a space.
Unicode:
JavaScript does not support this natively!
If you want to support Unicode letters instead of only the old ASCII letters, then replace
[a-z] with \p{L}. You can then also remove the i modifier, since \p{L} is a Unicode property that matches all letters in any language (only complete letters, not combined ones, there you could use [\p{L}\p{Mn}\p{Mc}])
Here's how I'd do it.
<?php
$symbols = '!~*:;<>+#\-£$&_?(){}\[\]';
$regex = "/^(?=.*[$symbols])(?=.{6,15}\$)(?!.* )[a-zA-Z][a-zA-Z0-9 $symbols]+[a-zA-Z0-9]$";
?>
If any of the following explanations are unclear, please ask, referring to their number:
Note that we've factored out the list of symbols for convenience.
Note that we've escaped -, [, and ], as these are meaningful characters in character classes. It's possible to not escape them as long as the - is at the beginning or end, and the ] is at the beginning, but since we're mixing $symbols with other characters, we can't be sure where the "beginning" or "end" really is.
(?=...) are known as lookaheads. They're useful for asserting multiple conditions. For example, the (?=.*[$symbols]) asserts that there is a symbol somewhere (hence the .*); and the (?=.{6,15}\$) asserts that, from beginning to end, the string is between 6 and 15 characters in length (note that the $ is escaped only because it exists in a double-quote).
The (?!...) is known as a negative lookahead. The (?!.* ) asserts that there are no two consecutive spaces anywhere.
The remainder should be obvious.
Like suggested by #Juhana in the comments, why not test your rules separately rather than make a single over complex regex? something like this. (these are not actual solutions or tested as you didn't provide any test strings, more an example of how to think differently about your problem)
Javascript
function verify(string) {
var length = string.length;
if (length < 6 || length > 15 || /^\d/.test(string) || /^\s/.test(string) || /\s$/.test(string) || /\s\s/.test(string) || /[!~*:;<>+#-£$&_?(){}[\]]+/.test(string)) {
return false;
}
return true;
}
PHP
function verify($string) {
$length = strlen($string);
if ($length < 6 || $length > 15 || preg_match("/^\d/", $string) || preg_match("/^\s/", $string) || preg_match("/\s$/", $string) || preg_match("/\s\s/", $string) || preg_match("/[!~*:;<>+#-£$&_?(){}[\]]+/", $string)) {
return false;
}
return true;
}
Hi I need to use php's pregmatch to check a string is valid. In order to be valid the string needs to have at least one uppercase character, at least one lowercase character, and then at least one symbol or number
thanks
You can achieve this by using lookaheads
^(?=.*[a-z])(?=.*[A-Z])(?=.*[\d,.;:]).+$
See it here on Regexr
A lookahead is a zero width assertion, that means it does not match characters, it checks from its position if the assertion stated is true. All assertions are evaluated separately, so the characters can be in any order.
^ Matches the start of the string
(?=.*[a-z]) checks if somewhere in the string is a lowercase character
(?=.*[A-Z]) checks if somewhere in the string is a uppercase character
(?=.*[\d,.;:]) checks if somewhere in the string is a digit or one of the other characters, add those you want.
.+$ Matches the string till the end of the string
As soon as one of the Assertions fail, the complete regex fail.
If the match has to be in the order you've described, you could use
$result = preg_match('/[A-Z]+[a-z]+[\d!$%^&]+/', $string);
If the characters can be in any order I'm not so sure, without doing three separate checks like so:
$result = (preg_match('/[A-Z]+/', $string) && preg_match('/[a-z]+/', $string) && preg_match('/[\d!$%^&]+/', $string));
As people have pointed out below, you can do this all in one regular expression with lookaheads.
According to your request:
[A-Z]+ Match any uppercase char
[a-z]+ Match any lowercase char
[\d§$%&]+ Match a number or special chars (add more special if you need to)
The result would look like this: [A-Z]+[a-z]+[\d§$%&]+
This isn't ideal though. You might want to check Regexr and try what kind of regex fits your requirements.
If you want these not to be necessarily in order, you need a lookahead. The following expression will validate for at least one lower char, one upper char and one number:
$result = preg_match('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])', $string);
You can put a lot of special chars with the numbers, like this:
$result = preg_match('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9$%])', $string);
I've written a regular expression in PHP to allow strings that are alpha-numeric with any punctuation except & or #. Essentially, I need to allow anything on a standard American keyboard with the exception of those two characters. It took me a while to come up with the following regex, which seems to be doing what I need:
if (ereg("[^]A-Za-z0-9\[!\"#$%'()*+,./:;<=>?^_`{|}~\-]", $test_string)) {
// error message goes here
}
Which brings me to my question... is there a better, simpler, or more efficient way?
Have a look at character ranges:
#[!-%'-?A-~]+#
This will exclude the characters & (\0x26) and # (0x40).
Looking at an ASCII Table,you can see how this works:
The exclamation mark is the first character in the ASCII set, that is not whitespace. It will then match everything up to and including the % character, which immediately precedes the ampersand. Then the next range until the # character, which lies between ? and A. After that, we match everything unto the end of the standard ASCII character set which is a ~.
Update
To make things more readable, you might also consider to do this in two steps:
At first, filter anything outside of the default ASCII range.
#[!-~]+#
In a second step, filter your undesired characters, or simply do a str_pos on the characters.
At the end, you can compare it with what you started to see whether it contained any undesired characters.
Instead, you could also use a regex such as this for the second step.
/[^#&]+/
The steps are interchangeable and doing a str_pos on # or & as a first step, to identify bad characters, may be better performance wise.
What about this:
[^&#]
with preg_match
$str = 'a';
var_dump(preg_match('~^[^&#]+$~', $str)); // true
$str = '&';
var_dump(preg_match('~^[^&#]+$~', $str)); // false
$str = '!';
var_dump(preg_match('~^[^&#]+$~', $str)); // true
I think rather than testing for all the alpha numeric characters you can simply check for # and & and use a not?
$reg = '/#|&/';
if(!preg_match($reg, "YOUR STRING CAN GO HERE")){
// your code goes here
}