问题
In a PHP variable I have some text that contains some keywords. These keywords are currently capitalised. I would like them to remain capitalised and be wrapped in curly brackets but once only. I am trying to write upgrade code but each time it runs it wraps the keywords in another set of curly brackets.
What REGEX do I need to use to match the keyword alone without also matching it if it is {KEYWORD}.
For example, the text variable is:
$string = "BLOGNAME has posted COUNT new item(s),
TABLE
POSTTIME AUTHORNAME
You received this e-mail because you asked to be notified when new updates are posted.
Best regards,
MYNAME
EMAIL";
And my upgrade code is:
$keywords = array('BLOGNAME', 'BLOGLINK', 'TITLE', 'POST', 'POSTTIME', 'TABLE', 'TABLELINKS', 'PERMALINK', 'TINYLINK', 'DATE', 'TIME', 'MYNAME', 'EMAIL', 'AUTHORNAME', 'LINK', 'CATS', 'TAGS', 'COUNT', 'ACTION');
foreach ($keywords as $keyword) {
$regex = '|(^\{){0,1}(\b' . $keyword . '\b)(^\}){0,1}|';
$replace = '{' . $keyword . '}';
$string = preg_replace($regex, $replace, $string);
}
My REGEX is currently not working well at all, it is stripping some spaces and also on each run placing more curly brackets around most (but not all) keywords. What am I doing wrong? Can someone correct my regex?
回答1:
You are looking for negative assertions. They are not written using the ^
syntax as in character classes but as (?<!...)
and (?!...)
. In your case:
'|(?<!\{)(\b' . $keyword . '\b)(?!\})|';
回答2:
- It will work if keyword does not contain special char.
- (A1) rows can be removed from regex, if source text can not contain {keyword} or necessary to leave '{}' symbols around keywords in result text (was {keyword} need {{keyword}} for formatting as example)
$text = <<<EOF
BLOGNAME has posted COUNT new item(s),
TABLE
POSTTIME AUTHORNAME
You received this e-mail because you asked to be notified when new updates are posted.
Best regards,
MYNAME
EMAIL
EOF;
$aKeywords = array('BLOGNAME', 'BLOGLINK', 'TITLE', 'POST', 'POSTTIME', 'TABLE', 'TABLELINKS', 'PERMALINK', 'TINYLINK', 'DATE', 'TIME', 'MYNAME', 'EMAIL', 'AUTHORNAME', 'LINK', 'CATS', 'TAGS', 'COUNT', 'ACTION');
$keywords = implode('|', $aKeywords);
$reSrch = '/
(?<!\{) # (A1) prev symbol is not {
\b # begin of word
('.$keywords.') # list of keywords
\b # end of word
(?!\{) # (A1) next symbol is not {
/xm'; // m - multiline search & x - ignore spaces in regex
$reRepl = '{\1}';
$result = preg_replace($reSrch, $reRepl, $text);
echo '<pre>';
// echo '$reSrch:'.$reSrch.'<hr>';
echo $result.'<br>';
回答3:
Why regex? Just use str_replace
:
foreach ($keywords as $k) {
$string = str_replace($k, '{'.$k.'}', $string);
}
来源:https://stackoverflow.com/questions/6056472/regex-to-match-keyword-if-not-enclosed-by-curly-braces