preg_replace 无法按预期处理数字字符串数据
preg_replace doesn't work as expected with numeric string data
当我处理以数字字符开头的字符串时,我注意到一个奇怪的 preg_replace()
行为:替换字符串的第一个字符(第一个数字)被截断。我在 PHP 5.6.36 和 PHP 7.0.30.
中看到它
此代码:
<?php
$items = array(
'1234567890' => '<a href="http://example.com/1234567890">1234567890</a>',
'1234567890 A' => '<a href="http://example.com/123456789-a">1234567890 A</a>',
'A 1234567890' => '<a href="http://example.com/a-1234567890">A 1234567890</a>',
'Only Text' => '<a href="http://example.com/only-text">Only Text</a>',
);
foreach( $items as $title => $item ) {
$search = '/(<a href="[^"]+">)[^<]+(<\/a>)/';
$replace = '' . $title . '';
// Preserve for re-use.
$_item = $item;
// Doesn't work -- the titles starting with a number are wonky.
$item = preg_replace( $search, $replace, $item );
echo 'Broken: ' . $item . PHP_EOL;
// Ugly hack to fix the issue.
if ( is_numeric( substr( $title, 0, 1 ) ) ) {
$title = ' ' . $title;
}
$replace = '' . $title . '';
$_item = preg_replace( $search, $replace, $_item );
echo 'Fixed: ' . $_item . PHP_EOL;
}
产生这个结果:
Broken: 234567890</a>
Fixed: <a href="http://example.com/1234567890"> 1234567890</a>
Broken: 234567890 A</a>
Fixed: <a href="http://example.com/123456789-a"> 1234567890 A</a>
Broken: <a href="http://example.com/a-1234567890">A 1234567890</a>
Fixed: <a href="http://example.com/a-1234567890">A 1234567890</a>
Broken: <a href="http://example.com/only-text">Only Text</a>
Fixed: <a href="http://example.com/only-text">Only Text</a>
我已经在 https://regex101.com/ 在线测试了我的正则表达式,据我所知,它写得正确。 (恕我直言,这并不复杂。)
这是 PHP 错误,还是我没有完全理解我的正则表达式?
看来我的 $replace
参数 ('' . $title . ''
) 是罪魁祸首。由于 $title 以数字开头,它被添加到 $1,所以 $replace
看起来像 234...
.
解决方案:
$replace = '%s';
.
.
.
echo sprint( $item, $title );
...优点是不会在我的页面标题链接中引入虚假空格。
为了避免这种行为,只需将 </code> 更改为 <code>
,与 </code></p> 相同
<pre><code>foreach( $items as $title => $item ) {
$search = '/(<a href="[^"]+">)[^<]+(<\/a>)/';
$replace = '' . $title . '';
...
当我处理以数字字符开头的字符串时,我注意到一个奇怪的 preg_replace()
行为:替换字符串的第一个字符(第一个数字)被截断。我在 PHP 5.6.36 和 PHP 7.0.30.
此代码:
<?php
$items = array(
'1234567890' => '<a href="http://example.com/1234567890">1234567890</a>',
'1234567890 A' => '<a href="http://example.com/123456789-a">1234567890 A</a>',
'A 1234567890' => '<a href="http://example.com/a-1234567890">A 1234567890</a>',
'Only Text' => '<a href="http://example.com/only-text">Only Text</a>',
);
foreach( $items as $title => $item ) {
$search = '/(<a href="[^"]+">)[^<]+(<\/a>)/';
$replace = '' . $title . '';
// Preserve for re-use.
$_item = $item;
// Doesn't work -- the titles starting with a number are wonky.
$item = preg_replace( $search, $replace, $item );
echo 'Broken: ' . $item . PHP_EOL;
// Ugly hack to fix the issue.
if ( is_numeric( substr( $title, 0, 1 ) ) ) {
$title = ' ' . $title;
}
$replace = '' . $title . '';
$_item = preg_replace( $search, $replace, $_item );
echo 'Fixed: ' . $_item . PHP_EOL;
}
产生这个结果:
Broken: 234567890</a>
Fixed: <a href="http://example.com/1234567890"> 1234567890</a>
Broken: 234567890 A</a>
Fixed: <a href="http://example.com/123456789-a"> 1234567890 A</a>
Broken: <a href="http://example.com/a-1234567890">A 1234567890</a>
Fixed: <a href="http://example.com/a-1234567890">A 1234567890</a>
Broken: <a href="http://example.com/only-text">Only Text</a>
Fixed: <a href="http://example.com/only-text">Only Text</a>
我已经在 https://regex101.com/ 在线测试了我的正则表达式,据我所知,它写得正确。 (恕我直言,这并不复杂。)
这是 PHP 错误,还是我没有完全理解我的正则表达式?
看来我的 $replace
参数 ('' . $title . ''
) 是罪魁祸首。由于 $title 以数字开头,它被添加到 $1,所以 $replace
看起来像 234...
.
解决方案:
$replace = '%s';
.
.
.
echo sprint( $item, $title );
...优点是不会在我的页面标题链接中引入虚假空格。
为了避免这种行为,只需将 </code> 更改为 <code>
,与 </code></p> 相同
<pre><code>foreach( $items as $title => $item ) {
$search = '/(<a href="[^"]+">)[^<]+(<\/a>)/';
$replace = '' . $title . '';
...