Expecting output is not displaying from php code - php

This is the code:
<?php
$pattern =' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$text = "kdaiuyq7e611422^^$^vbnvcn^vznbsjhf";
$text_split = str_split($text,1);
$data = '';
foreach($text_split as $value){
if (preg_match("/".$value."/", $pattern )){
$data = $data.$value;
}
if (!preg_match('/'.$value.'/', $pattern )){
break;
}
}
echo $data;
?>
Current output:
kdaiuyq7e611422^^$^vbnvcn^vznbsjhf
Expected output:
kdaiuyq7e611422
Please help me editing my code error. In pattern there is no ^ or $. But preg_match is showing matched which is doubtful.

You string $text have ^ which will match the begin of the string $pattern.
So the preg_match('/^/', $pattern) will return true, then the ^ will append to $data.
You should escape the ^ as a raw char, not a special char with preg_match('/\^/', $pattern) by the help of preg_quote() which will escape the special char.

There is no need to split your string up like that, the whole point of a regular expression is you can specify all the conditions within the expression. You can condense your entire code down to this:
$pattern = '/^[[:word:] ]+/';
$text = 'kdaiuyq7e611422^^$^vbnvcn^vznbsjhf';
preg_match($pattern, $text, $matches);
echo $matches[0];

Kris has accurately isolated that escaping in your method is the monkey wrench. This can be solved with preg_quote() or wrapping pattern characters in \Q ... \E (force characters to be interpreted literally).
Slapping that bandaid on your method (as you have done while answering your own question) doesn't help you to see what you should be doing.
I recommend that you do away with the character mask, the str_split(), and the looped calls of preg_match(). Your task can be accomplished far more briefly/efficiently/directly with a single preg_match() call. Here is the clean way that obeys your character mask fully:
Code: (Demo)
$text = "kdaiuyq7e611422^^$^vbnvcn^vznbsjhf";
echo preg_match('/^[a-z\d ]+/i',$text,$out)?$out[0]:'No Match';
Output:
kdaiuyq7e611422
miknik's method was close to this, but it did not maintain 100% accuracy given your question requirements. I'll explain:
[:word:] is a POSIX Character Class (functioning like \w) that represents letters(uppercase and lowercase), numbers, and an underscore. Unfortunately for miknik, the underscore is not in your list of wanted characters, so this renders the pattern slightly inaccurate and may be untrustworthy for your project.

Related

PHP preg_match to allow only numbers,spaces '+' and '-'

I need to check to see if a variable contains anything OTHER than 0-9 and the "-" and the "+" character and the " "(space).
The preg_match I have written does not work. Any help would be appreciated.
<?php
$var="+91 9766554433";
if(preg_match('/[0-9 +\-]/i', $var))
echo $var;
?>
You have to add a * as a quantifier to the whole character class and add anchors to the start and end of the regex: ^ and $ means to match only lines containing nothing but the inner regex from from start to end of line. Also, the i modifier is unnecessary since there is no need for case-insensitivity in this regex.
This should do the work.
if(!preg_match('/^[0-9 +-]*$/', $var)){
//variable contains char not allowed
}else{
//variable only contains allowed chars
}
Just negate the character class:
if ( preg_match('/[^0-9 +-]/', $var) )
echo $var;
or add anchors and quantifier:
if ( preg_match('/^[0-9 +-]+$/', $var) )
echo $var;
The case insensitive modifier is not mandatory in your case.
You can try regex101.com to test your regex to match your criteria and then on the left panel, you'll find code generator, which will generate code for PHP, Python, and Javascript.
$re = "/^[\\d\\s\\+\\-]+$/i";
$str = "+91 9766554433";
preg_match($re, $str, $matches);
You can take a look here.
Try see if this works. I haven't gotten around to test it beforehand, so I apologize if it doesn't work.
if(!preg_match('/^[0-9]+.-.+." ".*$/', $var)){
//variable contains char not allowed
}else{
//variable only contains allowed chars
}

PHP - How to set regex boundary and not match non alphanumeric char?

Consider the following:
$text = 'c c++ c# and other text';
$skills = array('c','c++','c#','java',...);
foreach ($skill as $skill) {
if (preg_match('/\b'.$skill.'\b/', $text)) {
echo $skill.' is matched';
}
}
In the case of 'c', it matches 'c', 'c#', and 'c++'. I've tried appending assertion (?=\s) or [\s|.] in place of \b towards the end but it needs something similar to \b.
I've checked out other posts but doesn't seem to have the exact situation. Thanks!
The problem is that \b matches between c and + or #. You need something like this:
$text = 'c c++ c# and other text';
$skills = array('c','c++','c#','java');
foreach ($skills as $skill) {
if (preg_match('/(?<=^|\s)'.preg_quote($skill).'(?:\s|$)/', $text)) {
echo $skill.' is matched';
}
}
This matches when the text is preceded by either the start of the string (^) or a space at the beginning, and followed by either the end of the string ($) or a space at the end.
You need to use preg_quote(), like I did above, because c++ contains regex special characters.
Also, note the typo (missing s) in foreach ($skills ... ) in your original code.
Part of the problem is that c++ has regex chars in it. You should use preg_quote on $skill. Then use your back and forward reference solution.
The other issue is that you need to double escape the special characters because php also uses \ as an escape character in strings.

How to remove unneeded parenthesis in a string?

I have a string containing a mathematical expression, like (21)*(4+2). For the purposes of computing, I need to "simplify" it so that it doesn't contain any number between expression (i.e. (21)*(4+2) => 21*(4+2)). I have no idea of how to do it (I thought of something with regex replaces, but I'm not very good at handling it).
you can do an algorithm something like this:
$str = "(21)*(4+2)";
//split above to array of characters
$arr = str_split($str);
foreach($arr as $i => $char) {
if character is opening parenthesis {
get all characters in a string until closing parnethesis is found
endif }
if the string you received from above contains only digits
(means it has no expression i.e. +,-,/,%,*) then remove the first and last
characters of the above string which are the parenthesis and append the
string to the final string.
}
Okay, it seems to me that I accidently solved the problem(so far, the preg_replace works for me):
echo preg_replace( "/\((\d+)\)/", "$1", $eq );
It doesn't take into account the decimals, I think. The sample equation and output it generates is here on codepad.
For decimals, I used a [\d\.]+ in the regex. It seems to be working.
echo preg_replace( "/\(([\d\.]+)\)/", "$1", $eq );
Another link.

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.

Regex, get string value between two characters

I'd like to return string between two characters, # and dot (.).
I tried to use regex but cannot find it working.
(#(.*?).)
Anybody?
Your regular expression almost works, you just forgot to escape the period. Also, in PHP you need delimiters:
'/#(.*?)\./s'
The s is the DOTALL modifier.
Here's a complete example of how you could use it in PHP:
$s = 'foo#bar.baz';
$matches = array();
$t = preg_match('/#(.*?)\./s', $s, $matches);
print_r($matches[1]);
Output:
bar
Try this regular expression:
#([^.]*)\.
The expression [^.]* will match any number of any character other than the dot. And the plain dot needs to be escaped as it’s a special character.
this is the best and fast to use
function get_string_between ($str,$from,$to) {
$string = substr($str, strpos($str, $from) + strlen($from));
if (strstr ($string,$to,TRUE) != FALSE) {
$string = strstr ($string,$to,TRUE);
}
return $string;
}
If you're learning regex, you may want to analyse those too:
#\K[^.]++(?=\.)
(?<=#)[^.]++(?=\.)
Both these regular expressions use possessive quantifiers (++). Use them whenever you can, to prevent needless backtracking. Also, by using lookaround constructions (or \K), we can match the part between the # and the . in $matches[0].

Categories