if (preg_match('#^https?://account.oneplus.net/invite/claim/....-....-....-....#', $url) === 0) {
return "Invalid link";
}
I currently use this code (in PHP) to verify the url. However, it also passes as true when you try with other stuff trailing behind the link. How do I fix this so that only links ending with or without / work?
This was the regex I was looking for:
preg_match('#^https?://account.oneplus.net/invite/claim/\S{4}-\S{4}-\S{4}-\S{4}/?$#', $url) === 0
I suggest you to replace all the dots with \S (which matches any non-space character), so .... would be written as \S{4} because . would match also a horizontal space. And also add the pattern (/?) to match an optional / at the last.
Related
i use preg_match() function in php to find match inside string.
**$var="you can find in telegram.org/";
if(preg_match("(?=(?!(telegram\.org).*)",&var)>0)
{
echo "ok";
}else{
echo "fault";
}**
i want to print fault.
It seems you may use
if (preg_match('~^(?!.*telegram\.org/).*telegram\.org~', $var)) {
echo "OK";
}
See the regex demo.
This pattern will match any string containing telegram.org but not telegram.org/.
Details
^ - start of string
(?!.*telegram\.org/) - no telegram.org/ anywhere in the string is allowed
.* - any 0+ chars other than line break chars
telegram\.org - a telegram.org substring.
NOTE You need a regex if you want to match the telegram.org as a whole word:
'~^(?!.*\btelegram\.org/).*\btelegram\.org\b~'
Check the \b, word boundary. Else, you might consider other, non-regex ways to match the string. Like the one below, but - perhaps, better - with stripos, for a case insensitive comparison.
I recommend not using regex for this. strpos() is fast and can do this task well.
Here is a demo that only needs to call strpos() twice:
$vars=["you can find in telegram.org/","you can find in telegram.org","telegram.org here"];
$find='telegram.org';
foreach($vars as $var){
if(strpos($var,$find)!==false && strpos($var,$find.'/')===false){
echo "$find found without /\n";
}else{
echo "$find failed\n";
}
}
Output:
telegram.org failed
telegram.org found without /
telegram.org found without /
If you are set on regex, I think ~telegram\.org(?!/)~ does the job well enough. Just check for the string and see that it is not immediately followed by a /.
I am trying to use preg_match to figure out if a url has certain pattern and right now its not working as I expected. Heres what I have so far:
if(! preg_match('^lease/([0-9]+)/?', $url)) {
wp_redirect( home_url(), 301 );
}
Basically I want to see if the url pattern is as below(lease keyword followed by a number) and if not the page should be redirected to homepage. Im not good with regex so I need some help with this one. TIA.
www.example.com/lease/324
You need to allow any chars before the /lease with .*?, an end of string anchor $ and regex delimiters (I prefer ~ so as not to escape forward slashes):
if(! preg_match('~^.*/lease/([0-9]+)/?$~', $url)
Or you may omit ^.*? part since preg_match allows partial matches
if(! preg_match('~/lease/([0-9]+)/?$~', $url)
You don't need the capture group (parenthesis) unless you want to know what the trailing numbers are. But looks like you just want to check if it contains lease/{number}
You can try this:
if (! preg_match("/lease\/[0-9]+/", $url)) {
wp_redirect( home_url(), 301);
}
contains lease, then a slash, then 1+ number
given a string:
//foo.bar/baz/123/index.html
I am trying to match the number after baz, so long as it is not 123.
//foo.bar/baz/124/index.html (WOULD MATCH)
//foo.bar/baz/123/index.html (WOULD NOT MATCH)
How can I express this? I keep trying things like:
/baz\/d+^(123)/index/
but have not been successful. Any help is appreciated!
Use negative look-ahead to assert that there is not 123 after baz/. Then go on to match with \d+:
m~baz/(?!123\b)\d+/index~
In Perl, you can use different delimiter when your regex pattern already contains /, to avoid escaping them. Here I've used ~.
If the substring to not allow is fixed to be baz/123, you can also do it with index() function:
$str = "//foo.bar/baz/124/index.html";
$needle = "/baz/123/";
if (index($str, $needle) == -1) {
print "Match found\n";
}
I'm trying to replace:
*facebook.com/
with http://graph.facebook.com/
I need to be able to group anything before the facebook.com part into an optional group.
I can't just replace facebook.com with graph.facebook.com because the incoming URL may contain https.
Here's what I have but misses anything that doesn't have http[s]://.
<?php
$fb_url = preg_replace('/http[s]*:\/\/[www.]*facebook.com\//', 'http://graph.facebook.com/', 'facebook.com/some/segments');
echo $fb_url;
?>
Addressing your question specifically:
You can make any single character (or a group of characters) optional by adding a ? after it in your regex.
A couple of tips from looking at your code:
If you are matching strings containing / characters, simplify your life by using a different delimiter (for example #). You aren't required to use a forward slash.
You should escape the . dot metacharacter because it matches ANY single character, so your expression www. could conceivably match www9 or anything else along those lines
Also, the brackets [...] are for matching a range of characters. If you want to match specifically the text www. you should use a non-captured group like (?:www\.) and make it optional by adding the ? after it like (?:www\.)?
So, those tips in mind, try ...
<?php
$p = '#(?:https?://(?:www\.)?)?facebook\.com/#';
$r = 'http://graph.facebook.com/';
$subject = 'facebook.com/some/segments';
$fb_url = preg_replace($p, $r, $subject);
echo $fb_url; // outputs: http://graph.facebook.com/some/segments
?>
use something like below
(optional-regex-here)?
I'm trying to understand what's wrong with this regex pattern:
'/^[a-z0-9-_\.]*[a-z0-9]+[a-z0-9-_\.]*{4,20}$/i'
What I'm trying to do is to validate the username. Allowed chars are alphanumeric, dash, underscore, and dot. The restriction I'm trying to implement is to have at least one alphanumeric character so the user will not be allowed to have a nickname like this one: _-_.
The function I'm using right now is:
function validate($pattern, $string){
return (bool) preg_match($pattern, $string);
}
Thanks.
EDIT
As #mario said, yes,t here is a problem with *{4,20}.
What I tried to do now is to add ( ) but this isn't working as excepted:
'/^([a-z0-9-_\.]*[a-z0-9]+[a-z0-9-_\.]*){4,20}$/i'
Now it matches 'aa--aa' but it doesn't match 'aa--' and '--aa'.
Any other suggestions?
EDIT
Maybe someone wants to deny not nice looking usernames like "_..-a".
This regex will deny to have consecutive non alphanumeric chars:
/^(?=.{4,20}$)[a-z0-9]{0,1}([a-z0-9._-][a-z0-9]+)*[a-z0-9.-_]{0,1}$/i
In this case _-this-is-me-_ will not match, but _this-is-me_ will match.
Have a nice day and thanks to all :)
Don't try to cram it all into one regex. Make your life simpler and use a two step-approach:
return (bool)
preg_match('/^[a-z0-9_.-]{4,20}$/', $s) && preg_match('/\w/', $s);
The mistake in your regex probably was the mixup of * and {n,m}. You can have only one of those quantifiers, not *{4,20} both after another.
Very well, here is the cumbersome solution to what you want:
preg_match('/^(?=.{4})(?!.{21})[\w.-]*[a-z][\w-.]*$/i', $s)
The assertions assert the length, and the second part ensures that at least one letter is present.
Try this one instead:
'/[a-z0-9-_\.]*[a-z0-9]{1,20}[a-z0-9-_\.]*$/i'
Its probably just a matter if finetuning, you could try something like this:
if (preg_match('/^[a-zA-Z0-9]+[_.-]{0,1}[a-zA-Z0-9]+$/m', $subject)) {
# Successful match
} else {
# Match attempt failed
}
Matches:
a_b <- you might not want this.
ysername
Username
1254_2367
fg3123as
Non-Matches:
l__asfg
AHA_ar3f!
sAD_ASF_#"#T_
"#%"&#"E
__-.asd
username
1___
Non-matches you might want to be matches:
1_5_2
this_is_my_name
It is clear to me that you should split this into two checks!
Firstly check that they are using all valid characters. If they're not, then you can tell them that they are using invalid characters.
Then check that they have at least one alpha-numeric character. If they're not, then you can tell them that they must.
Two distinct advantages here: more meaningful feedback to the user and cleaner code to read and maintain.
Here is a simple, single regex solution (verbose):
$re = '/ # Match password having at least one alphanum.
^ # Anchor to start of string.
(?=.*?[A-Za-z0-9]) # At least one alphanum.
[\w\-.]{4,20} # Match from 4 to 20 valid chars.
\z # Anchor to end of string.
/x';
In Action (short form):
function validate($string){
$re = '/^(?=.*?[A-Za-z0-9])[\w\-.]{4,20}\z/';
return (bool) preg_match($re, $string);
}
Try this:
^[a-zA-Z][-\w.]{0,22}([a-zA-Z\d]|(?<![-.])_)$
From related question: Create one RegEx to validate a username
^[A-Za-z][A-Za-z0-9]*(?=.{3,31}$)[a-z0-9]{0,1}([a-z0-9._-][a-z0-9]+)*[a-z0-9.-_]{0,1}$
This will Validate the username
start with an alpha
accept underscore dash and dots
no spaces allowed
Why don't you make it simpler like this?
^[a-zA-Z][a-zA-Z0-9\._-]{3,9}
First letter should be Alphabetical.
then followed by character or symbols you allowed
length of the word should be between 4,10 (as explicitly force the first word)