Bookmark and Share

Wednesday, February 24, 2010

One-stop-shop preg.


If you use perl regular expressions on a regular basis then you probably have come across the following lines of code extensively:


if (preg_match($expression, $subject, $matches)) {
$iCareAbout = $matches[1];

Occasionaly you also needed to replace the first matched instance. Which if you also wanted to check if matches were replaced and what the matches are is more cumbersome:


if (preg_match($expression, $subject, $matches)) {
$iCareAbout = $matches[1];
preg_replace($expression, $replace, $subject, 1);

For both of these instances the RawDev preg function looks as follows:


$iCareAbout = RUtil::preg($expression, $subject); # case 1
$iCareAbout = RUtil::preg($expression, $subject, $replace); # case 2


In addition, the RawDev preg function can match/replace all instances. Lastly, it can handle an array of strings as the subject of which only the strings that matched were returned.


static mixed function preg($regex, $subject, $replace, $all, $alwaysArray)

Returns the matches of a perl regular expression in an array (getting rid of the unnecessary first element that preg_match generates) ; the result is returned in a scalar if one variable is matched (\1) and alternatively in array. The matches can also be replaced.
$regexstringThe full regular expression (including options such as "/.../ice").
$subjectmixedThe subject is a string or an array of strings that is subject to modification (passed in by reference).
$replaceboolThe optional replacement string (accepts variables such as "1").
$allboolWhether one or all instances should be matched/replaced (default: all=false).
$alwaysArrayboolBy default when only one variable is matched, it is returned as a scalar (e.g. by default"/ (a) /" is returned as scalar, "/ (a) (b) /" as an array). Setting this to true will always return the matches as an array.
returnsmixedThe match or matches. This can be a string, an array of strings or an array of an array of strings (match all). Null when no matches.


This example works on the string: "[USA] Gold, [Netherlands] Silver, [Canada] Bronze"

It matches/replaces the first country and then all countries.

The result is:



$str = "[USA] Gold, [Netherlands] Silver, [Canada] Bronze";

$str1 = $str;
$str2 = $str;
$str3 = $str;
$str4 = $str;

# find first country
$result1 = RUtil::preg("/\[(.*?)\]/", $str1);
# find and replace first country
$result2 = RUtil::preg("/\[(.*?)\]/", $str2, "\\1");
# find all countries
$result3 = RUtil::preg("/\[(.*?)\]/", $str3, NULL, true);
# find and replace all countries
$result4 = RUtil::preg("/\[(.*?)\]/", $str4, "\\1", true);



Using RUtil::preg code will reduce the amount of code you produce. Which will, in the long run, save (a) programming hours, (b) reduce bugs and (c) increase execution performance (less code to put in memory). The subject is changed by reference. This can be annoying because you need to assign a temporary var if you don't want to change the subject. Always use preg_replace when you don't care about returning matches.


RUtil API Doc

No comments:

Post a Comment