I'm having a some trouble formatting my regular expression for my PHP code using preg_match().
I have a simple string usually looking like this:
"q?=%23asdf".
I want my regular expression to only pass true if the string begins with "q?=%23" and there is a character at the end of the 3. So far one of the problems I have had is that the ? is being pulled up by the regex so doing something like
^q?=23 doesn't work. I am also having problems with contiguous searching in Regex expressions (because I can't figure out how to search after the 3).
So for clarification: "q?=%23asd" should PASS and "q?=%23" should FAIL
I'm no good with Regex so sorry if this seems like a beginner question and thanks in advance.
Just use a lookahead to check whether the character following 3 is an alphabet or not,
^q\?=%23(?=[a-zA-Z])
Add . instead of [A-Za-z] only if you want to check for any character following 3,
^q\?=%23(?=.)
Code would be,
$theregex = '~^q\?=%23(?=[a-z])~i';
if (preg_match($theregex, $yourstring)) {
// Yes! It matches!
}
else { // nah, no luck...
}
So the requirement is: Start with q?=%23, followed by at least one [a-z], the pattern could look like:
$pattern = '/^q\?=%23[a-z]+/i';
Used i (PCRE_CASELESS) modifier. Also see example at regex101.
$string = "q?=%23asdf";
var_dump(figureOut($string));
function figureOut($string){
if(strpos($string, 'q?=%23') == 0){
if(strlen($string) > 6){
return true;
}else{ return false;}
}
}
Related
I have a text, for example, like: $descrizione = "Tel.+39.1234.567899 asd.test#testwebsite.com
www.testwebsite.com" and I would like to obtain three different variable with:
"+39.1234.567899""asd.test#testwebsite.com"
"www.testwebsite.com".
To check if text contains email I use regex and I write this code:
$regex = '/[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})/';
if (preg_match($regex, $descrizione, $email_is)) {
for($e = 0; $e < count($email_is) ; $e++){
if(strpos($email_is[$e], "#") !== false){
$linkEmail = $email_is[$e];
}
}
}
now, I would like to find website url, so I try to write:
$regex = '/[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/gi';
if( preg_match($regex, $descrizione, $matches)){
$linkWebsite = $matches[0];
}
but the preg_match return false. I control the regex with the website http://regexr.com/ and it's correct, so I don't understand why return always false. Where is the problem?I try to use "/[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/" but I have the same problem and I try to check errors with trycatch but it doesn't return errors.
Finally I would like to find phone number but I don't know how to write regex.
Is there someone thet can help me, please?
Your regex fails because it's faulty. You've escaped the slashes (/) with slashes. You should use backslashes:
[-a-zA-Z0-9#:%_\+.~#?&\/=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&\/=]*)?
Here at regex101.
Since regexr uses JS regex it doesn't complain, but if you try it at regex101 selecting php you'll easily detect such errors.
About regex for phone numbers - search! E.g https://stackoverflow.com/search?q=%5Bregex%5D+phone+number
I have find the solution, I hope thet this can help someone.
The preg_match returns only first result and not all the result thet it has find.
So, if I check the regex using a website like regex101, it returns the corrects result with all matches, but if I use the same regex in php, it returns only one.
The regex option "g" (global = don't return after first match) corresponds to the function preg_match_all.
I try to make system that can detect date in some string, here is the code :
$string = "02/04/16 10:08:42";
$pattern = "/\<(0?[1-9]|[12][0-9]|3[01])\/\.- \/\.- \d{2}\>/";
$found = preg_match($pattern, $string);
if ($found) {
echo ('The pattern matches the string');
} else {
echo ('No match');
}
The result i found is "No Match", i don't think that i used correct regex for the pattern. Can somebody tell me what i must to do to fix this code
First of all, remove all gibberish from the pattern. This is the part you'll need to work on:
(/0?[1-9]|[12][0-9]|3[01]/)
(As you said, you need the date only, not the datetime).
The main problem with the pattern, that you are using the logical OR operators (|) at the delimiters. If the delimiters are slashes, then you need to replace the tube characters with escaped slashes (/). Note that you need to escape them, because the parser will not take them as control characters. Like this: \/.
Now, you need to solve some logical tasks here, to match the numbers correctly and you're good to go.
(I'm not gonna solve the homework for you :) )
These articles will help you to solve the problem tough:
Character classes
Repetition opetors
Special characters
Pipe character (alternation operator)
Good luck!
In your comment you say you are looking for yyyy, but the example says yy.
I made a code for yy because that is what you gave us, you can easily change the 2 to a 4 and it's for yyyy.
preg_match("/((0|1|2|3)[0-9])\/\d{2}\/\d{2}/", $string, $output_array);
Echo $output_array[1]; // date
Edit:
If you use this pattern it will match the time too, thus make it harder to match wrong.
((0|1|2|3)[0-9])/\d{2}/\d{2}\s+\d{2}:\d{2}:\d{2}
http://www.phpliveregex.com/p/fjP
Edit2:
Also, you can skip one line of code.
You first preg_match to $found and then do an if $found.
This works too:
If(preg_match($pattern, $string, $found))}{
Echo $found[1];
}Else{
Echo "nothing found";
}
With pattern and string as refered to above.
As you can see the found variable is in the preg_match as the output, thus if there is a match the if will be true.
I have the following check currently to match if a string is a not a number
if (!ctype_digit($matching)) {
}
however now I wanted to change this such that I wanted to detect the following format:
xxxk
xxxrb
xxx.xxxx
or any numbers
What is the best regular expression to detect this? X here is an integer/digits between 0-9 and it can be any length. So for example, here's a valid match:
8k
72k
123k
899rb
20rb
5rb
160.000
1.600.218
You can use this regex:
^\d{1,3}(?:k|rb|(?:\.\d{3})+|\d+)$
Working demo
The php code is:
$re = "/^\\d{1,3}(?:k|rb|(?:\\.\\d{3})+|\\d+)$/m";
$str = "8k\n72k\n123k\n899rb\n20rb\n5rb\n160.000\n1.600.218";
preg_match_all($re, $str, $matches);
Allow me offer a generic solution based on what I understood about your format.
In Regular Expression you can use | meaning or so based on your multiple format those can be expressed with or's like this:
x{3}k|x{3}rb|x{3}\.x{4}|\d+
Online Demo
Each |(or) represents one of the formats(expression) you may be allowing/evaluating.
Since x is not specify in your post please note x can be easily replaced by letters with [a-zA-Z] expression or by numbers with [0-9] expression or a combination of both like [a-zA-Z0-9].
you can use this:
\A\d+(?:(?:\.\d{3})*|k|rb)\z
Based on the strings you would like to match, here is the regex:
/^\d[0-9a-z\.]+$/i
Working example (please keep in mind that I added the g and m parameters so it would match each example)
If you need to make sure that all decimal points have 3 digits after them then it gets a little more complex:
/^\d{1,3}(?:\.\d{3}?)*(?:[a-z]+)?$/i
More complex example
Update:
Now works according to all new examples.
<?php
$matching = "120.000";
$re = "/^(\b\d{1,3}|k|rb|\.\d{3}\b)*$/";
if (!ctype_digit($matching)) {
if (!preg_match($re, $matching, $matches)) {
echo "ctype_digit/regex not matched";
} else {
echo "regex pattern matched";
}
} else {
echo "ctype_digit matched";
}
?>
Another solution:
\d[.\d]*(?:rb|k)?
I want to check whether the search keyword 'cli' or 'ent' or 'cl' word exists in the string 'client' and case insensitive. I used the preg_match function with the pattern '\bclient\b'. but it is not showing the correct result. Match not found error getting.
Please anyone help
Thanks
I wouldn't use regular expressions for this, it's extra overhead and complexity where a regular string function would suffice. Why not go with stripos() instead?
$str = 'client';
$terms = array('cli','ent','cl');
foreach($terms as $t) {
if (stripos($str,$t) !== false) {
echo "$t exists in $str";
break;
}
}
Try the pattern /cli?|ent/
Explanation:
cli matches the first part. The i? makes the i optional in the search.
| means or, and that matches cli, or ent.
\b is word boundary, It would not match cli in client, you need to remove \b
I have an input field where both regular text and sprintf tags can be entered.
Example: some text here. %1$s done %2$d times
How do I validate the sprintf parts so its not possible them wrong like %$1s ?
The text is utf-8 and as far as I know regex only match latin-1 characters.
www.regular-expressions.info does not list /u anywhere, which I think is used to tell that string is unicode.
Is the best way to just search the whole input field string for % or $ and if either found then apply the regex to validate the sprintf parts ?
I think the regex would be: /%\d\$(s|d|u|f)/u
I originally used Gumbo's regex to parse sprintf directives, but I immediately ran into a problem when trying to parse something like %1.2f. I ended up going back to PHP's sprintf manual and wrote the regex according to its rules. By far I'm not a regex expert, so I'm not sure if this is the cleanest way to write it:
/%(?:\d+\$)?[+-]?(?:[ 0]|'.{1})?-?\d*(?:\.\d+)?[bcdeEufFgGosxX]/
The UTF-8 modifier is not necessary unless you use UTF-8 in your pattern. And beside that the sprintf format is more complex, try the following
/%(?:\d+\$)?[dfsu]/
This would match both the %s and %1$s format.
But if you want to check every occurrence of % and whether a valid sprintf() format is following, regular expressions would not be a good choice. A sequential parser would be better.
This is what I ended up with, and its working.
// Always use server validation even if you have JS validation
if (!isset($_POST['input']) || empty($_POST['input'])) {
// Do stuff
} else {
$matches = explode(' ',$_POST['input']);
$validInput = true;
foreach ($matches as $m) {
// Check if a slice contains %$[number] as it indicates a sprintf format
if (preg_match('/[%\d\$]+/',$m) > 0) {
// Match found. Now check if its a valid sprintf format
if ($validInput === false || preg_match('/^%(?:\d+\$)?[dfsu]$/u',$m)===0) { // no match found
$validInput = false;
break; // Invalid sprintf format found. Abort
}
}
}
if ($validInput === false) {
// Do stuff when input is NOT valid
}
}
Thank you Gumbo for the regex pattern that matches both with and without order marking.
Edit: I realized that searching for % is wrong, since nothing will be checked if its forgotten/omitted. Above is new code.
"$validInput === false ||" can be omitted in the last if-statement, but I included it for completeness.