Capturing some different part of text and replacing with another - regex

There is a deprecated function in PHP and for that reason, I need to replace all functions with their replacements. Since some of the arguments have different values, I need to use a regex find-and-replace method to do this.
For example I have two functions:
mysql_result($one,0,"val1")
mysql_result($two,0,"val2")
How can I write a regex to convert this two into those?
$one["val1"]
$two["val2"]
Currently I have (mysql_result\()*\"\) but this only matches the ending part of the function.

You can use this pattern, then substitute with $1["$2"]:
.*?\(([^,]+).*?"([^"]+).*
Live DEMO
Edit:
$string = array('mysql_result($one,0,"val1")', 'mysql_result($two,0,"val2")');
$pattern = '/.*?\(([^,]+).*?"([^"]+).*/';
print_r( preg_replace($pattern, '$1["$2"]', $string ));
Working DEMO

preg_replace('/mysql_result\(([^,]*),[^,]*,([^)]*)\)/', '$1[$2]', $string);

Use following regexRegEx: (mysql_result\()(.*),(.*),(.*)(\))
And replace it with following: \2[\4]

Related

Make a regular expression in perl to grep value work on a string with different endings

I have this code in perl where I want to extract the value of 'EUR_AF', in this case '0.39'.
Sometimes 'EUR_AF' ends with ';', sometimes it doesn't.
Alternatively, 'EUR_AF' may end with '=0' instead of '=0.39;' or '=0.39'.
How do I make the code handle that? Can't seem to find it online...I could of course wrap everything in an almost endless if-elsif-else statement, but that seems overkill.
Example text:
AVGPOST=0.9092;AN=2184;RSQ=0.5988;ERATE=0.0081;AC=144;VT=SNP;THETA=0.0045;AA=A;SNPSOURCE=LOWCOV;LDAF=0.0959;AF=0.07;ASN_AF=0.05;AMR_AF=0.10;AFR_AF=0.11;EUR_AF=0.039
Code: $INFO =~ m/\;EUR\_AF\=(.*?)(;)/
I did find that: $INFO =~ m/\;EUR\_AF\=(.*?0)/ handles the cases of EUR_AF=0, but how to handle alternative scenarios efficiently?
Extract one value:
my ($eur_af) = $s =~ /(?:^|;)EUR_AF=([^;]*)/;
my ($eur_af) = ";$s" =~ /;EUR_AF=([^;]*)/;
Extract all values:
my %rec = split(/[=;]/, $s);
my $eur_af = $rec{EUR_AF};
This regex should work for you: (?<=EUR_AF=)\d+(\.\d+)?
It means
(?<=EUR_AF=) - look for a string preceeded by EUR_AF=
\d+(\.\d+)? - consist of a digit, optionally a decimal digit
EDIT: I originally wanted the whole regex to return the correct result, not only the capture group. If you want the correct capture group edit it to (?<=EUR_AF=)(\d+(?:\.\d+)?)
I have found the answer. The code:
$INFO =~ m/(?:^|;)EUR_AF=([^;]*)/
seems to handle the cases where EUR_AF=0 and EUR_AF=0.39, ending with or without ;. The resulting $INFO will be 0 or 0.39.

Regex: re-using a pattern within a group to use in another group

Hopefully I can explain this properly.
Is it possible to re-use part of my regular to re-use somewhere else within the regex? For example, say you have: \d{3} (could be a lot more complex. Made it simple for the purpose of the question) and you want to test this with a combination of either [a-zA-Z]{3,} or [\.a-zA-Z]{10}. This can be written as \d{3}([a-zA-Z]{3,}|[\.a-zA-Z]{10}). However, if I wish to use this again, perhaps in the regex, would it be possible or must you re-write this pattern again in order to re-use it. Any insight would be appreciated.
You can do this if you're using PCRE (and possibly other regex flavors) by using subpatterns, optionally within a (DEFINE) condition.
The examples below are in PHP for demonstration purposes. The definition of (?<digits>\d{3}) and reference of it with (?&digits) is done within the regular expression itself.
Example:
preg_match(
'/(?<digits>\d{3})([a-zA-Z]{3,}|[\.a-zA-Z]{10})(?&digits)/',
'123abc456',
$matches);
var_dump($matches[0]);
Output:
string(9) "123abc456"
Define Example:
$regex = <<<'REGEX'
/
(?(DEFINE)
# A define condition allows you to create subpatterns for use by reference only.
(?<digits>\d{3})
(?<letters>[a-zA-Z]{3,}|[\.a-zA-Z]{10})
)
(?&digits)((?&letters))(?&digits)
/x
REGEX;
preg_match($regex, '123abc456', $matches);
var_dump($matches[0]);
Output:
string(9) "123abc456"
For a more complex example see my answer here on creating a syntax parser for a simple grammar.
You can do it in whatever programming language you're using to execute the regexp. E.g. in PHP you can do:
$subre = '\d{3}([a-zA-Z]{3,}|[\.a-zA-Z]{10})';
if (preg_match("/{$subre}blah{$subre}/", $string)) {
...
;
I know this is old, but you can accomplish this using pure Regex, using recursion.
Here i name your group as 'name', then i simply reused it twice at the end
(?'name'\d{3})([a-zA-Z]{3,}|[\.a-zA-Z]{10})\g'name'\g'name'

Match everything except every given combination

Given string, for example abbbabf
given piece, for example ab
Needed, that remove all characters, except every pieces, that is from abbbabf must get result: abab
How should be regex pattern for this ?
Edit
Lets take php as example
Its simply to remove everyting, except piece, if piece is just one symbol, that is if piece is a, must do
$str = "abbbabf";
echo preg_replace("#[^a]#", "", $str);
and result is aa
But how to make this when piece is more than one symbol, I have no idea...
Please dont give solutions such as:
preg_match_all("#ab#", $str, $a);
echo implode($a[0]);
Thanks
PS. I need make this In ORACLE database and if I find solution (one pattern) without procedure handling, will be cool.
The following can do it using capture groups rather than assertions:
$str = "helloababblolobbbabf";
^^^^ ^^
echo preg_replace("#.*?(ab|$)#", "$1", $str);
// Output: ababab
RegExr
Since you say you're actually working in Oracle, you can use REGEXP_REPLACE:
REGEXP_REPLACE(input, '.*?(ab|$)', '\1')
SQLFiddle
The expression you need to use is this:
((?<=ab|^).*?(?=ab|$))
From the string, abbbabfasdfsdfsdfab ababab is returned.
See it in action: http://regex101.com/r/nT8mC1
Caveat as Bart points out in a comment, Oracle doesn't implement much of the PCRE standard, and as such this simply won't work. You'll have to look at implementing some sort of capture set where you can capture the string you want and rebuild it with implode (which you don't want to do apparently).
Edit added suggestion for conditional from comments.

Regex position string

For example i have this string.
$string = 'test***bas';
How can I display text before the stars with Regex?
You could use a regular expression which makes use of Capture Groups. Once that you have matched your input, you could then access the captured group and print the output.
The following pattern
^(.+?)\*\*\*
will create a group match using the parenthesis operators. See http://gskinner.com/RegExr/ for testing your regular expressions (there are many ways of testing online)
The language you use around your regular expression will have different ways of capturing groups so you will need to better explain what language you are using for any further advice.
Example for before and after asterix
^(.+?)\*\*\*(.+)$
If tou also want what is located after the ***, you can use the following:
$string = 'test***bas';
$pattern = '/(.+)\*{3}(.+)/';
preg_match($pattern, $string, $matches);
$matches will contain the results:
$matches[1] will be "test"
$matches[2] will be "bas"

extract substring using regex

I would like to extract the string between "t=" and '&' from the string below, but '&2384' may not be present sometimes. I have tried the following, but I get the result "123455asdfgh&2384" instead of "123455asdfgh", what am I doing wrong here? thanks for help.
$string="t=123455asdfgh&2384";
$match=array();
preg_match('/t=(.*)(&.*)?/', $string, $match);
echo $match[1];
NOTE: I need to use regular exp...
Try this one instead
preg_match('/t=([^&]*)(&.*)?/', $string, $match);
This is better suited for parse_str(), and not a regex.
parse_str( "t=123455asdfgh&2384", $params);
echo $params['t'];
This prints:
123455asdfgh
This is what parse_str is for (parsing query strings):
$string="t=123455asdfgh&2384";
$args = array();
parse_str($string, $args);
echo $args['t']; // outputs '123455asdfgh'
Try a non greedy quantifier:
preg_match('/t=(.*?)(?=&|$)/', $string, $match);
The problem is that the first .* matches everything up till the end of the string, which is still a complete match because the latter group is optional.
How about using the strpos() to find the starting and ending point in the string, and then extract it?