First off, when writing a complex regex, it helps to write it out using free-spacing mode with lots of comments. Here is your regex with added comments:
Code: Select all
<?php
$prefix = 'prefix_';
$str = '<select name="course">';
$re = '/
(<\s*input[^>]+) # $1: INPUT opening tag, everthing up to "name".
(\s*name\s*=\s*) # $2: "name = " attribute, equals sign, optional ws.
(\'|"?)\s* # $3: Single or optional double quote, optional ws.
(\w+)\s* # $4: First word of "name" attribute value, optional ws.
(\'|"?\s+) # $5: Single or optional double quote, one or more ws.
([^>]*>) # $6: Remainder of INPUT opening tag.
/six';
$str = preg_replace($re, "\\1"."\\2"."\\3".$prefix."\\4"."\\5"."\\6", $str);
echo $str;
// I want it to return <select name="prefix_course">
?>
The problem is the subexpression for the closing quote: "('|\"?\s+)". It says: "
Match and capture either a single quote or an optional double quote followed by one or more spaces." The first reason your regex does not match is because there are no spaces following the closing quote in the subject string. Secondly, your regex specifies an INPUT tag when I think you are trying to match a SELECT tag. Here is an improved version:
Code: Select all
<?php
$prefix = 'prefix_';
$str = '<select name="course">';
$re = '/
( # $1: Everything up to name attribute value.
<select # Opening delim and tagname.
[^>]+? # Lazily match everything up to "name" attribute.
\bname\s*=\s* # "name = " attribute and equals sign with optional ws.
) # End $1. Everything up to name attribute value.
([\'"]?)\s* # $2: Optional single or double quote, optional ws.
(\w+)\s* # $3: First word of "name" value, optional ws.
(?(2)\2) # If value had opening quote, match same closing quote.
([^>]*>) # $4: Remainder of input opening tag.
/ix';
$str = preg_replace($re, '$1"' . $prefix . '$3"$4', $str);
echo $str;
?>
Hope this helps!
