php preg_match fails when used with a variable - php

Excuse me, I am making a terrible mistake somewhere, but this is the situaton:
In php i have:
$ln = "A/RADIUS ADMITS VALUE 20";
$trg = "A/RADIUS";
$matches = array();
$zz = preg_match('#$trg\sADMITS\s(VALUE)\s([^\s]+)#',$ln,$matches);
I want to capture the word "VALUE" without quotes and the last word, here the string 20, given by ([^\s]+) . That is not a whitespace repeated more than once right?
But $zz is 0, indicating no match and $matches is empty. I also tried with
$zz = preg_match('#'.$trg.'\sADMITS\s(VALUE)\s([^\s]+)#',$ln,$matches);
same problem.
Where is the mistake I am stupidly making?

You are using single quotes to embed the $trg variable in the string, which only works when using double quotes to enclose the string. This should work:
$zz = preg_match("#$trg\sADMITS\s(VALUE)\s([^\s]+)#",$ln,$matches);

Related

PHP - Regular Expressions with Double Quoted Strings

I'm trying to use regular expressions to extract a certain value from a string:
"exec_hash": "/TPPE2ChB+5HuSHs84FBgx5/EgWi0OlaEXoXq4pq3Aukhc1Ypf0mZfKCJ10w=", "events_collector": "thiiM0ahsieSiech1phithe6chahngoo8sah6aid\n"
The data I want is the hash between the quotation marks. The problem is that there are multiple quotes within the string and preg_match_all function isn't returning the correct data. I've been playing around with regex for a while but can't figure it out. Ultimately, I'd like that data to be returned into a value. Ex: $string1 = '/TPPE2ChB+5HuSHs84FBgx5/EgWi0OlaEXoXq4pq3Aukhc1Ypf0mZfKCJ10w=';
Correction: I'm using curl to grab the page content. The data isn't stored in a variable.
$matches = array();
$thing = preg_match_all('/hash": "(.*?)", "events/',$page,$matches); print_r($matches);
It spits out a long array of much more than just the hash
Can you use substr?
haven't tested this, but in theory...
$pos_of_comma = strpos($str, ",");
if($pos_of_comma !== false) {
$execHash = substr($str, 14, $pos_of_comma - 14);
}
It looks like it's json_decodable:
//Get the result from curl request:
$curlResult = '"exec_hash": "/TPPE2ChB+5HuSHs84FBgx5/EgWi0OlaEXoXq4pq3Aukhc1Ypf0mZfKCJ10w=", "events_collector": "thiiM0ahsieSiech1phithe6chahngoo8sah6aid\n"';
//Parse the result:
$parsedResult = json_decode($curlResult, true);
//Get the hash:
$hash = $parsedResult["exec_hash"];
Thank you for the suggestions.
I figured it out. I missed the escape delimiters in the expression.
preg_match_all("/exec_hash\": \"(.*?)\", /",$page,$matches);

Get html or text from inside quotes including escape quotes with RegEx

What I want to do is to get the attribute value from a simple text I'm parsing. I want to be able to contain HTML as well inside the quotes, so that's what got me stalling right now.
$line = 'attribute = "<p class=\"qwerty\">Hello World</p>" attribute2 = "value2"'
I've gotten to the point (substring) where I'm getting the value
$line = '"<p class=\"qwerty\">Hello World</p>" attribute2 = "value2"'
My current regex works if there are no escaped quotes inside the text. However, when I try to escape the HTML quotes, it doesn't work at all. Also, using .* is going to the end of the second attribute.
What I'm trying to obtain from the string above is
$result = '<p class=\"qwerty\">Hello World</p>'
This is how far I've gotten with my trial and error regex-ing.
$value_regex = "/^\"(.+?)\"/"
if (preg_match($value_regex, $line, $matches))
$result = $matches[1];
Thank you very much in advance!
You can use negative lookbehind to avoid matching escaped quotes:
(?<!\\)"(.+?)(?<!\\)"
RegEx Demo
Here (?<!\\) is negative lookbehind that will avoid matching \".
However I would caution you on using regex to parse HTML, better to use DOM for that.
PHP Code:
$value_regex = '~(?<!\\\\)"(.+?)(?<!\\\\)"~';
if (preg_match($value_regex, $line, $matches))
$result = $matches[1];

Get and replace quoted strings with regex

I'm trying to get strings inside a quote.
I'm using regex but i have problems with escaped quotes.
For example, i have this:
$var = "SELECT * FROM TABLE WHERE USERNAME='Carasuman'";
preg_match_all('~([\'"])(.*?)\1~s', $var, $result);
$new = preg_replace('~([\'"])(.*?)\1~s',"<#################>",$var);
The code Works perfect. I got a replaced value in $new and quoted value in $result[1]
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>";
$result[1] = "Carasuman";
My problem is when i add a scaped quote inside quotes:
$var = "SELECT * FROM TABLE WHERE USERNAME='Carasuman\'s'";
I got this:
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>'s";
$result[1] = "Carasuman\" //must be "Carasuman\'s";
How I can avoid this error and get $new and $result[1] like first example?:
$new = "SELECT * FROM TABLE WHERE USERNAME=<#################>";
$result[1] = "Carasuman\'s";
Thanks!
for the match, you're never going to get Carasuman's without the \ as a single matched element since you can have match skip over chars within a single match. its either going to grab the Carasuman or Carasuman\'sjust use str_replace to get rid of the backslash
preg_match_all('~([\'"])(.*)\1~s', $var, $result);
$result[2] = str_replace('\\','',$result[2]);
for the replace, the ? in the (.*?) group makes it ungreedy, meaning it will stop at the first match. Remove the ? in (.*?) to make it greedy, meaning it will keep going until the last match
preg_replace('~([\'"])(.*)\1~s',"<#################>",$var);
Edit
Rather than doing the str_replace after the match on $result[2], it would probably be better to just do beforehand on the initial string like:
$var = str_replace("\\'","'",$var);
preg_match_all('~([\'"])(.*)\1~s', $var, $result);
$new = preg_replace('~([\'"])(.*)\1~s',"<#################>",$var);
You still need to make your wildcard match greedy like (.*?) to (.*) in order to have the apostrophe in the name included in the match/replace instead of being counted as the terminating single quote
Why don't you do this:
$var = "SELECT * FROM TABLE WHERE USERNAME='" . mysql_real_escape_string($input) . "'";
I don't think you necessarily need to do regex. Also, mysql_real_escape_string properly escapes your inputs so you can just have $input = 'Carasuman\'s'; or $input = "Carasuman's";
To match quoted strings, you could use the regex '\'.*?(?:\\\\.[^\\\\\']*)*\'' and four double quoted strings '".*?(?:\\\\.[^\\\\"]*)*"'

How to remove commas between double quotes in PHP

Hopefully, this is an easy one. I have an array with lines that contain output from a CSV file. What I need to do is simply remove any commas that appear between double-quotes.
I'm stumbling through regular expressions and having trouble. Here's my sad-looking code:
<?php
$csv_input = '"herp","derp","hey, get rid of these commas, man",1234';
$pattern = '(?<=\")/\,/(?=\")'; //this doesn't work
$revised_input = preg_replace ( $pattern , '' , $csv_input);
echo $revised_input;
//would like revised input to echo: "herp","derp,"hey get rid of these commas man",1234
?>
Thanks VERY much, everyone.
Original Answer
You can use str_getcsv() for this as it is purposely designed for process CSV strings:
$out = array();
$array = str_getcsv($csv_input);
foreach($array as $item) {
$out[] = str_replace(',', '', $item);
}
$out is now an array of elements without any commas in them, which you can then just implode as the quotes will no longer be required once the commas are removed:
$revised_input = implode(',', $out);
Update for comments
If the quotes are important to you then you can just add them back in like so:
$revised_input = '"' . implode('","', $out) . '"';
Another option is to use one of the str_putcsv() (not a standard PHP function) implementations floating about out there on the web such as this one.
This is a very naive approach that will work only if 'valid' commas are those that are between quotes with nothing else but maybe whitespace between.
<?php
$csv_input = '"herp","derp","hey, get rid of these commas, man",1234';
$pattern = '/([^"])\,([^"])/'; //this doesn't work
$revised_input = preg_replace ( $pattern , "$1$2" , $csv_input);
echo $revised_input;
//ouput for this is: "herp","derp","hey get rid of these commas man",1234
It should def be tested more but it works in this case.
Cases where it might not work is where you don't have quotes in the string.
one,two,three,four -> onetwothreefour
EDIT : Corrected the issues with deleting spaces and neighboring letters.
Well, I haven't been lazy and written a small function to do exactly what you need:
function clean_csv_commas($csv){
$len = strlen($csv);
$inside_block = FALSE;
$out='';
for($i=0;$i<$len;$i++){
if($csv[$i]=='"'){
if($inside_block){
$inside_block=FALSE;
}else{
$inside_block=TRUE;
}
}
if($csv[$i]==',' && $inside_block){
// do nothing
}else{
$out.=$csv[$i];
}
}
return $out;
}
You might be coming at this from the wrong angle.
Instead of removing the commas from the text (presumably so you can then split the string on the commas to get the separate elements), how about writing something that works on the quotes?
Once you've found an opening quote, you can check the rest of the string; anything before the next quote is part of this element. You can add some checking here to look for escaped quotes, too, so things like:
"this is a \"quote\""
will still be read properly.
Not exactly an answer you've been looking for - But I've used it for cleaning commas in numbers in CSV.
$csv = preg_replace('%\"([^\"]*)(,)([^\"]*)\"%i','$1$3',$csv);
"3,120", 123, 345, 567 ==> 3120, 123, 345, 567

Preg_match, Replace and back to string

sorry but i cant solve my problem, you know , Im a noob.
I need to find something in string with preg_match.. then replace it with new word using preg_replace, that's ok, but I don't understand how to put replaced word back to that string.
This is what I got
$text ='zda i "zda"';
preg_match('/"(\w*)"/', $text);
$najit = '/zda/';
$nahradit = 'zda';
$o = '/zda/';
$a = 'if';
$ahoj = preg_replace($najit, $nahradit, $match[1]);
Please, can you help me once again?
You can use e.g. the following code utilizing negative lookarounds to accomplish what you want:
$newtext = preg_replace('/(?<!")zda|zda(?!")/', 'if', $text)
It will replace any occurence of zda which is not enclosed in quotes on both sides (i.e. in U"Vzda"W the zda will be replaced because it is not enclosed directly into quotes).

Categories