PHP: Regex for exact match - php

Here is the regex I currently have (which kind of works):
$regex = '/[\w ]{7,30}/';
My revision looks like what I want, but it does not work at all:
$regex = '^[\w ]{7,30}$';
Here is how I am using the regex:
public function isValid( $value )
{
$regex = '/^[\w ]{7,30}$/';
return preg_match( $regex, $value ) ? true : false;
}
I am trying to match the following:
Any lower/upper case letter
Any digit
Can contain spaces
Cannot contain line breaks or tab space
Minimum of 7 characters
Maximum of 30 characters
Valid inputs:
Testing
Test ing
Test123
Test 123
Test___
Invalid inputs:
Testing#
Testin8+
Tester1&
The first regex will match all valid inputs, as well as invalid (as long as the first four characters are valid, it doesn't care about the rest). The second regex matches nothing.

Try combining both like so:
$regex = '/^[\w ]{7,30}$/';

Don't forget your delimiters:
/^[\w ]{7,30}$/

You're missing the / at the beginning and end.
$regex = '/^[\w ]{7,30}$/';

'/^[\w ]{7,30}$/'
You're missing the delimiters.

Related

Check string for defined format and get part of it

How can I check if a string has the format [group|any_title] and give me the title back?
[group|This is] -> This is
[group|just an] -> just an
[group|example] -> example
I would do that with explode and [group| as the delimiter and remove the last ]. If length (of explode) is > 0, then the string has the correct format.
But I think that is not quite a good way, isn't it?
So you want to check if a string matches a regex?
if(preg_match('/^\[group\|(.+)\]$/', $string, $m)) {
$title = $m[1];
}
If the group part is supposed to be dynamic as well:
if(preg_match('/^\[(.+)\|(.+)\]$/', $string, $m)) {
$group = $m[1];
$title = $m[2];
}
Use regular expression matching using PHP function preg_match.
You can use for example regexr.com to create and test a regular expression and when you're done, then implement it in your PHP script (replace the first parameter of preg_match with your regular expression):
$text = '[group|This is]';
// replace "pattern" with regular expression pattern
if (preg_match('/pattern/', $text, $matches)) {
// OK, you have parts of $text in $matches array
}
else {
// $text doesn't contain text in expected format
}
Specific regular expression pattern depends on how strictly you want to check your input string. It can be for example something like /^\[.+\|(.+)\]$/ or /\|([A-Za-z ]+)\]$/. First checks if string starts with [, ends with ] and contains any characters delimited by | in between. Second one just checks if string ends with | followed by upper and lower case alphabetic characters and spaces and finally ].

Identifying a random repeating pattern in a structured text string

I have a string that has the following structure:
ABC_ABC_PQR_XYZ
Where PQR has the structure:
ABC+JKL
and
ABC itself is a string that can contain alphanumeric characters and a few other characters like "_", "-", "+", "." and follows no set structure:
eg.qWe_rtY-asdf or pkl123
so, in effect, the string can look like this:
qWe_rtY-asdf_qWe_rtY-asdf_qWe_rtY-asdf+JKL_XYZ
My goal is to find out what string constitutes ABC.
I was initially just using
$arrString = explode("_",$string);
to return $arrString[0] before I was made aware that ABC ($arrString[0]) itself can contain underscores, thus rendering it incorrect.
My next attempt was exlpoding it on "_" anyway and then comparing each of the exploded string parts with the first string part until I get a semblance of a pattern:
function getPatternABC($string)
{
$count = 0;
$pattern ="";
$arrString = explode("_", $string);
foreach($arrString as $expString)
{
if(strcmp($expString,$arrString[0])!==0 || $count==0)
{
$pattern = $pattern ."_". $arrString[$count];
$count++;
}
else break;
}
return substr($pattern,1);
}
This works great - but I wanted to know if there was a more elegant way of doing this using regular expressions?
Here is the regex solution:
'^([a-zA-Z0-9_+-]+)_\1_\1\+'
What this does is match (starting from the beginning of the string) the longest possible sequence consisting of the characters inside the square brackets (edit that per your spec). The sequence must appear exactly twice, each time followed by an underscore, and then must appear once more followed by a plus sign (this is actually the first half of PQR with the delimiter before JKL). The rest of the input is ignored.
You will find ABC captured as capture group 1.
So:
$input = 'qWe_rtY-asdf_qWe_rtY-asdf_qWe_rtY-asdf+JKL_XYZ';
$result = preg_match('/^([a-zA-Z0-9_+-]+)_\1_\1\+/', $input, $matches);
if ($result) {
echo $matches[2];
}
See it in action.
Sure, just make a regular expression that matches your pattern. In this case, something like this:
preg_match('/^([a-zA-Z0-9_+.-]+)_\1_\1\+JKL_XYZ$/', $string, $match);
Your ABC is in $match[1].
If the presence of underscores in these strings has a low frequency, it may be worth checking to see if a simple explode() will do it before bothering with regex.
<?php
$str = 'ABC_ABC_PQR_XYZ';
if(substr_count($str, '_') == 3)
$abc = reset(explode('_', $str));
else
$abc = regexy_function($str);
?>

Regex Problem in PHP

I'm attempting to utilize the following Regex pattern:
$regex = '/Name: [a-zA-Z ]*] [0-9]/';
When testing it in Rubular, it works fine, but when using PHP the expression never returns true, even when it should. Incidentally, if I remove the "[0-9]" part, it works fine. Is there some difference in PHP's regex syntax that I'm overlooking?
Edit:
I'm looking for the characters "Name:" then a name containing any number of letters or spaces, then a "]", then a space, then a single number. So
"Name: Chris] 5" would return true and
"Name: Chris] [lorem ipsum]" should return false.
I also tried escaping the second bracket "\[" but this did not fix the problem.
It's not clear without examples what your use case, but it seems like you want something like this?
$regex = '/Name\:\ ([\w]+)\ ([\w]+)/';
Update: try this:
$regex = '/Name\:\ [\w\s]+?\]\ [\d]{1}/';
For me this matches
Name: Foo Bar] 2
..but not these:
Name: Foo Bar] foo
Name: Foo Baz 5
I'm also using short-hand expressions for character classes:
[\w] is short for [a-zA-Z0-9] ( eg all alphanumeric characters )
[\s] matches any whitespace
[\d] matches any number
For safety I'm also using the '?' to match in a non-greedy way, to make sure thw [\w\s]+ match doesn't consume too much of the string.
i think this might be because of the space in the regex also u want to escape the second ]. try
$regex = '/Name:\s[a-zA-Z ]*\]\s[0-9]/';
Or use a modifier
$regex = '/Name: [a-zA-Z ]*\] [0-9]/x';
more on modifiers here
PHP: Possible modifiers in regex patterns - Manual
Your regex works nicely for me with the two examples you gave.
$arr = array('Name: Chris] 5', 'Name: Chris] [lorem ipsum]');
foreach ($arr as $str) {
if (preg_match('/Name: [a-zA-Z ]*] [0-9]/', $str)) {
echo "$str : OK\n";
} else {
echo "$str : KO\n";
}
}
Output:
Name: Chris] 5 : OK
Name: Chris] [lorem ipsum] : KO
May be there are more than one space between ] and the digit, so your regex should be:
[a-zA-Z ]*]\s+[0-9]/
I ended up resolving the issue by attempting different regexes that did basically the same thing. This is what ended up working:
$regex = '/Name: [\w ]*][^[]{2}/';
Evidently the brackets weren't the problem, but there was something in my original code that wasn't working properly. Thank you everyone for all the help.

Extract a special hash from a string

I'm trying to extract the following pattern {#56DS1e5R9w7v} which is :
{
Hash
a-z, A-Z, 0-9 ( not necessarily an alphanumeric string )
}
Any ideas please?
Thank you
Try this pattern:
\{#([^}]*)\}
It should match all characters that are not }, and place the result in a captured group. You may want to change [^}]* to \w* or [A-Za-z0-9]* if that's problematic.
Example (also on ideone.com):
$str = "hello {#56DS1e5R9w7v} good people";
preg_match_all("/\{#([^}]*)\}/", $str, $matches);
Something like ({#[a-z0-9]+?}) ?
preg_match('/(\{#[a-z0-9]+?\})/i', $sString)
What about:
<?php
$code = '{#56DS1e5R9w7v}';
$matches = preg_match('/^\{#[a-zA-Z0-9]+\}$/', $code);
?>
This makes sure the string begins with a { the second char must be a #, the 3th char until } must be alpha numeric and it must end with a }.
Hope this helped!

PHP regular expression find and append to string

I'm trying to use regular expressions (preg_match and preg_replace) to do the following:
Find a string like this:
{%title=append me to the title%}
Then extract out the title part and the append me to the title part. Which I can then use to perform a str_replace(), etc.
Given that I'm terrible at regular expressions, my code is failing...
preg_match('/\{\%title\=(\w+.)\%\}/', $string, $matches);
What pattern do I need? :/
I think it's because the \w operator doesn't match spaces. Because everything after the equal sign is required to fit in before your closing %, it all has to match whatever is inside those brackets (or else the entire expression fails to match).
This bit of code worked for me:
$str = '{%title=append me to the title%}';
preg_match('/{%title=([\w ]+)%}/', $str, $matches);
print_r($matches);
//gives:
//Array ([0] => {%title=append me to the title%} [1] => append me to the title )
Note that the use of the + (one or more) means that an empty expression, ie. {%title=%} won't match. Depending on what you expect for white space, you might want to use the \s after the \w character class instead of an actual space character. \s will match tabs, newlines, etc.
You can try:
$str = '{%title=append me to the title%}';
// capture the thing between % and = as title
// and between = and % as the other part.
if(preg_match('#{%(\w+)\s*=\s*(.*?)%}#',$str,$matches)) {
$title = $matches[1]; // extract the title.
$append = $matches[2]; // extract the appending part.
}
// find these.
$find = array("/$append/","/$title/");
// replace the found things with these.
$replace = array('IS GOOD','TITLE');
// use preg_replace for replacement.
$str = preg_replace($find,$replace,$str);
var_dump($str);
Output:
string(17) "{%TITLE=IS GOOD%}"
Note:
In your regex: /\{\%title\=(\w+.)\%\}/
There is no need to escape % as its
not a meta char.
There is no need to escape { and }.
These are meta char but only when
used as a quantifier in the form of
{min,max} or {,max} or {min,}
or {num}. So in your case they are treated literally.
Try this:
preg_match('/(title)\=(.*?)([%}])/s', $string, $matches);
The match[1] has your title and match[2] has the other part.

Categories