PHP preg_replace 适用于所有类型的年份格式(YYYY、YYYY-YYYY、YYYY - YYYY)
PHP preg_replace for All Types of Year Formats (YYYY, YYYY-YYYY, YYYY - YYYY)
尝试仅使用 preg_replace 修改包含 2018
1950-2018
和 [=22 等年份格式的字符串(添加 html 换行符) =]
$j = preg_replace('/([0-9]{4}) - ([0-9]{4})/', '<br>* - </strong>', $j);
$j = preg_replace('/([0-9]{4})-([0-9]{4})/', '<br>* - ', $j);
$j = preg_replace('/\s+(19[5-9][0-9]|20(0[0-9]|10))\s+/', '<br>* </strong>', $j);
我的偏好是正则表达式为 1950
- 2020
年
前两个工作正常(虽然我在正确设置范围时遇到了问题),但最后一个正在捕获所有实例
喜欢:
* 2007
** 2008 - 2013
等等
尝试使用 ^
和 $
来表示开始和结束..但是第三个总是与前两个匹配。
我怎样才能完全分离这些年份格式,以便我可以单独更改每个格式?
示例代码:
<?php
$string = 'Detailed Applications: 2005-2006 Volkswagen | 2006 Volkswagen Golf 2.0L 1984CC 121Cu. In. l4 GAS SOHC Naturally Aspirated | 2005 Volkswagen Beetle 2.0L 1984CC 121Cu. In. l4 GAS DOHC Naturally Aspirated | 2005 - 2006 Volkswagen Golf';
echo $string;
echo '<br><br>';
$string = preg_replace('/([0-9]{4}) - ([0-9]{4})/', '<br /><strong>(YYYY - YYYY)* - </strong>', $string);
$string = preg_replace('/([0-9]{4})-([0-9]{4})/', '<br /><strong>(YYYY-YYYY)* - </strong>', $string);
$string = preg_replace('/(\d19[5-9][0-9]|20[0-9][0-9])(?!\s?-)/', '<br /><strong>(YYYY)* </strong>', $string);
echo $string;
产出
Detailed Applications:
(YYYY-YYYY)* 2005 -
(YYYY)* 2006 Volkswagen |
(YYYY)* 2006 Volkswagen Golf 2.0L 1984CC 121Cu. In. l4 GAS SOHC Naturally Aspirated |
(YYYY)* 2005 Volkswagen Beetle 2.0L 1984CC 121Cu. In. l4 GAS DOHC Naturally Aspirated |
(YYYY - YYYY)* 2005 -
(YYYY)* 2006
抱歉,真的很困惑。
基本上我正在做的是尝试循环它并做一个换行符(不分解字符串)...显然使用我的正则表达式它在它自己的行上输出每个...
尝试获得这样的输出
Detailed Applications:
(YYYY-YYYY)* 2005 - 2006 Volkswagen |
(YYYY)* 2006 Volkswagen Golf 2.0L 1984CC 121Cu. In. l4 GAS SOHC Naturally Aspirated |
(YYYY)* 2005 Volkswagen Beetle 2.0L 1984CC 121Cu. In. l4 GAS DOHC Naturally Aspirated |
(YYYY - YYYY)* 2005 - 2006
但是是的..这是我得到的最好的
$j = preg_replace('/([0-9]{4}) - ([0-9]{4})/', '<br /><strong>* - </strong>', $j);
$j = preg_replace('/([0-9]{4})-([0-9]{4})/', '<br /><strong>* - </strong>', $j);
$j = preg_replace('/(19[5-9][0-9]|20(0[0-9]|20))(?!\s?-)/', '<br /><strong>* </strong>', $j);
所以这是我脚本的实际摘录
2007 Chevy Silverado Pickup new body style models 2008-2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD 2007 GMC Sierra Pickup new body style models 2008-2013 GMC Sierra All Models 2014 GMC Sierra 2500HD 3500HD 2007-2013 Chevy Tahoe 2007-2013 Chevy Suburban 2007-2013 Chevy Avalanche 2007-2013 GMC Yukon Yukon XL Yukon Denali
整整一行(发布上面的示例脚本是因为这一行不包含 YYYY - YYYY
变体...)
输出是这样的
* 2007 Chevy Silverado Pickup new body style models
* 2008 - 2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD
* 2007 GMC Sierra Pickup new body style models
* 2008 - 2013 GMC Sierra All Models 2014 GMC Sierra 2500HD 3500HD
* 2007 - 2013 Chevy Tahoe
* 2007 - 2013 Chevy Suburban
* 2007 - 2013 Chevy Avalanche
* 2007 - 2013 GMC Yukon Yukon XL Yukon Denali
一切都很好,除了 * 2008 - 2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD
2014
没有换行...我也不知道如何计算年份范围(doh!)甚至引用此 javascript regex validate years in range
简化替换逻辑的一种方法是识别您想要在每 4 位数字年份后添加一个 <br>
,即 而不是 后跟破折号,或 space 和破折号。我们可以使用否定前瞻轻松地表达这一点:
(\d{4})(?!\s?-)
代码示例:
$input = "that contains year formats like 2018 1950-2018 and 1950 - 2018";
echo preg_replace("/(\d{4})(?!\s?-)/", "<br>", $input);
that contains year formats like 2018<br> 1950-2018<br> and 1950 - 2018<br>
preg_replace_callback()
将让您 validate/extract 您的目标子字符串并一次性进行条件替换。
- A
<br>
必须写在所有 year/year-ranges 之前,只要它不是字符串的最开始。第一个捕获组是 \s*
,因此它将在您的目标 year/year-range 之前捕获零个或多个白色 space 字符。此元素将始终作为 [1]
存在于 $m
数组中。
- 第二个捕获组是第一个或唯一的年份值。这是要实现的回调函数所必需的。这是
$m
数组中的 [2]
。
- 至于可选的第二年值,它必须跟在零个或多个白色-space之后,然后是一个连字符,然后是零个或多个白色-space。因为这个捕获组后面没有捕获组,所以 php 只会在找到时为这个组生成一个元素 --
isset()
用于检查 [3]
是否存在。
- 最初,我使用
\b
来确保年份值不是较大数字子串的子串,但您的字符串格式允许使用 white-space 匹配来确认准确匹配。
代码:(Demo) (Pattern Demo)
$string = "2007 Chevy Silverado Pickup new body style models 2008-2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD 2007 GMC Sierra Pickup new body style models 2008 - 2013 GMC Sierra All Models 2014 GMC Sierra 2500HD 3500HD 2007-2013 Chevy Tahoe 2007-2013 Chevy Suburban 2007 - 2013 Chevy Avalanche 2007-2013 GMC Yukon Yukon XL Yukon Denali";
echo preg_replace_callback('~(\s*)(19[5-9]\d|20[0-4]\d)(?:\s*-\s*(19[5-9]\d|20[0-4]\d))?(?=\s)~', function($m) {
//var_export($m); // un-comment if you want to see each $m array
//echo "\n---\n";
return (strlen($m[1]) ? "\n" : "")
. "<strong>*{$m[2]}"
. (isset($m[3]) ? " - {$m[3]}" : "")
. "</strong>";
},
$string);
输出:
<strong>*2007</strong> Chevy Silverado Pickup new body style models
<strong>*2008 - 2013</strong> Chevy Silverado All Models
<strong>*2014</strong> Chevy Silverado 2500HD 3500HD
<strong>*2007</strong> GMC Sierra Pickup new body style models
<strong>*2008 - 2013</strong> GMC Sierra All Models
<strong>*2014</strong> GMC Sierra 2500HD 3500HD
<strong>*2007 - 2013</strong> Chevy Tahoe
<strong>*2007 - 2013</strong> Chevy Suburban
<strong>*2007 - 2013</strong> Chevy Avalanche
<strong>*2007 - 2013</strong> GMC Yukon Yukon XL Yukon Denali
尝试仅使用 preg_replace 修改包含 2018
1950-2018
和 [=22 等年份格式的字符串(添加 html 换行符) =]
$j = preg_replace('/([0-9]{4}) - ([0-9]{4})/', '<br>* - </strong>', $j);
$j = preg_replace('/([0-9]{4})-([0-9]{4})/', '<br>* - ', $j);
$j = preg_replace('/\s+(19[5-9][0-9]|20(0[0-9]|10))\s+/', '<br>* </strong>', $j);
我的偏好是正则表达式为 1950
- 2020
前两个工作正常(虽然我在正确设置范围时遇到了问题),但最后一个正在捕获所有实例
喜欢:
* 2007
** 2008 - 2013
等等
尝试使用 ^
和 $
来表示开始和结束..但是第三个总是与前两个匹配。
我怎样才能完全分离这些年份格式,以便我可以单独更改每个格式?
示例代码:
<?php
$string = 'Detailed Applications: 2005-2006 Volkswagen | 2006 Volkswagen Golf 2.0L 1984CC 121Cu. In. l4 GAS SOHC Naturally Aspirated | 2005 Volkswagen Beetle 2.0L 1984CC 121Cu. In. l4 GAS DOHC Naturally Aspirated | 2005 - 2006 Volkswagen Golf';
echo $string;
echo '<br><br>';
$string = preg_replace('/([0-9]{4}) - ([0-9]{4})/', '<br /><strong>(YYYY - YYYY)* - </strong>', $string);
$string = preg_replace('/([0-9]{4})-([0-9]{4})/', '<br /><strong>(YYYY-YYYY)* - </strong>', $string);
$string = preg_replace('/(\d19[5-9][0-9]|20[0-9][0-9])(?!\s?-)/', '<br /><strong>(YYYY)* </strong>', $string);
echo $string;
产出
Detailed Applications:
(YYYY-YYYY)* 2005 -
(YYYY)* 2006 Volkswagen |
(YYYY)* 2006 Volkswagen Golf 2.0L 1984CC 121Cu. In. l4 GAS SOHC Naturally Aspirated |
(YYYY)* 2005 Volkswagen Beetle 2.0L 1984CC 121Cu. In. l4 GAS DOHC Naturally Aspirated |
(YYYY - YYYY)* 2005 -
(YYYY)* 2006
抱歉,真的很困惑。
基本上我正在做的是尝试循环它并做一个换行符(不分解字符串)...显然使用我的正则表达式它在它自己的行上输出每个...
尝试获得这样的输出
Detailed Applications:
(YYYY-YYYY)* 2005 - 2006 Volkswagen |
(YYYY)* 2006 Volkswagen Golf 2.0L 1984CC 121Cu. In. l4 GAS SOHC Naturally Aspirated |
(YYYY)* 2005 Volkswagen Beetle 2.0L 1984CC 121Cu. In. l4 GAS DOHC Naturally Aspirated |
(YYYY - YYYY)* 2005 - 2006
但是是的..这是我得到的最好的
$j = preg_replace('/([0-9]{4}) - ([0-9]{4})/', '<br /><strong>* - </strong>', $j);
$j = preg_replace('/([0-9]{4})-([0-9]{4})/', '<br /><strong>* - </strong>', $j);
$j = preg_replace('/(19[5-9][0-9]|20(0[0-9]|20))(?!\s?-)/', '<br /><strong>* </strong>', $j);
所以这是我脚本的实际摘录
2007 Chevy Silverado Pickup new body style models 2008-2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD 2007 GMC Sierra Pickup new body style models 2008-2013 GMC Sierra All Models 2014 GMC Sierra 2500HD 3500HD 2007-2013 Chevy Tahoe 2007-2013 Chevy Suburban 2007-2013 Chevy Avalanche 2007-2013 GMC Yukon Yukon XL Yukon Denali
整整一行(发布上面的示例脚本是因为这一行不包含 YYYY - YYYY
变体...)
输出是这样的
* 2007 Chevy Silverado Pickup new body style models
* 2008 - 2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD
* 2007 GMC Sierra Pickup new body style models
* 2008 - 2013 GMC Sierra All Models 2014 GMC Sierra 2500HD 3500HD
* 2007 - 2013 Chevy Tahoe
* 2007 - 2013 Chevy Suburban
* 2007 - 2013 Chevy Avalanche
* 2007 - 2013 GMC Yukon Yukon XL Yukon Denali
一切都很好,除了 * 2008 - 2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD
2014
没有换行...我也不知道如何计算年份范围(doh!)甚至引用此 javascript regex validate years in range
简化替换逻辑的一种方法是识别您想要在每 4 位数字年份后添加一个 <br>
,即 而不是 后跟破折号,或 space 和破折号。我们可以使用否定前瞻轻松地表达这一点:
(\d{4})(?!\s?-)
代码示例:
$input = "that contains year formats like 2018 1950-2018 and 1950 - 2018";
echo preg_replace("/(\d{4})(?!\s?-)/", "<br>", $input);
that contains year formats like 2018<br> 1950-2018<br> and 1950 - 2018<br>
preg_replace_callback()
将让您 validate/extract 您的目标子字符串并一次性进行条件替换。
- A
<br>
必须写在所有 year/year-ranges 之前,只要它不是字符串的最开始。第一个捕获组是\s*
,因此它将在您的目标 year/year-range 之前捕获零个或多个白色 space 字符。此元素将始终作为[1]
存在于$m
数组中。 - 第二个捕获组是第一个或唯一的年份值。这是要实现的回调函数所必需的。这是
$m
数组中的[2]
。 - 至于可选的第二年值,它必须跟在零个或多个白色-space之后,然后是一个连字符,然后是零个或多个白色-space。因为这个捕获组后面没有捕获组,所以 php 只会在找到时为这个组生成一个元素 --
isset()
用于检查[3]
是否存在。 - 最初,我使用
\b
来确保年份值不是较大数字子串的子串,但您的字符串格式允许使用 white-space 匹配来确认准确匹配。
代码:(Demo) (Pattern Demo)
$string = "2007 Chevy Silverado Pickup new body style models 2008-2013 Chevy Silverado All Models 2014 Chevy Silverado 2500HD 3500HD 2007 GMC Sierra Pickup new body style models 2008 - 2013 GMC Sierra All Models 2014 GMC Sierra 2500HD 3500HD 2007-2013 Chevy Tahoe 2007-2013 Chevy Suburban 2007 - 2013 Chevy Avalanche 2007-2013 GMC Yukon Yukon XL Yukon Denali";
echo preg_replace_callback('~(\s*)(19[5-9]\d|20[0-4]\d)(?:\s*-\s*(19[5-9]\d|20[0-4]\d))?(?=\s)~', function($m) {
//var_export($m); // un-comment if you want to see each $m array
//echo "\n---\n";
return (strlen($m[1]) ? "\n" : "")
. "<strong>*{$m[2]}"
. (isset($m[3]) ? " - {$m[3]}" : "")
. "</strong>";
},
$string);
输出:
<strong>*2007</strong> Chevy Silverado Pickup new body style models
<strong>*2008 - 2013</strong> Chevy Silverado All Models
<strong>*2014</strong> Chevy Silverado 2500HD 3500HD
<strong>*2007</strong> GMC Sierra Pickup new body style models
<strong>*2008 - 2013</strong> GMC Sierra All Models
<strong>*2014</strong> GMC Sierra 2500HD 3500HD
<strong>*2007 - 2013</strong> Chevy Tahoe
<strong>*2007 - 2013</strong> Chevy Suburban
<strong>*2007 - 2013</strong> Chevy Avalanche
<strong>*2007 - 2013</strong> GMC Yukon Yukon XL Yukon Denali