Regex fomatting and design for a query - php

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

Check if text contains url, email and phone number with php and regex

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.

PHP preg_match regular expression for find date in string

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.

regular expression to detect integers followed by some string format

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)?

compare portion of the string using php

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

Validate sprintf format from input field with regex

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.

Categories