我被存储在数组中的月份在意大利,像这样:
$array = [
"gennaio" => "1",
"febbraio" => "2",
"marzo" => "3",
"aprile" => "4",
"maggio" => "5",
"giugno" => "6",
"luglio" => "7",
"agosto" => "8",
"settembre" => "9",
"ottobre" => "10",
"novembre" => "11",
"dicembre" => "12"
];
我也得到了这个标题:
$title1 = "Nota_382_del_16 marzo_2016.pdf";
$title2 = "OCDPC 382 del 16_agosto_2016.pdf";
$title3 = "OCDPC_382_del 16 _agosto 2016.pdf";
$title4 = "OCDPC_382_dal 16agosto 2016.pdf";
$title5 = "OCDPC_382 dall 16luglio2016.pdf";
$title6 = "OCDPC_382 da 16agosto_2016.pdf";
$title7 = "OCDPC_382_del_16_settembre 2016.pdf";
$title8 = "OCDPC_382 di 16 _agosto.2016.pdf";
$title9 = "OCDPC_382_del-16-agosto 2016.pdf";
$title10 = "Dipartimento OCDPC 382_del-16-agosto-2016.pdf";
$title11 = "OCDPC_382 dall'16-febbraio-2016.pdf";
$title12 = "OCDPC_382 dal'16-agosto-2016 - Dipartimentocivile.pdf";
在每个标题中,我想获得完整的日期,如16 settembre 2016
,然后将其格式化为16/09/2016
。
我在格式化日期方面没有问题,但我的主要问题是使用正确的regex
来捕获它,然后将月份名称更改为数字。对于更改月份上的数字,我可以用switch
语句来管理它。
任何类型的帮助将不胜感激!
编辑:到现在为止,我是这样管理的:
(?<![^W_])?del?s*Kd+.?d+.?20[0-2][0-9]
当月份是由数字而不是名称引用时,实际的正则表达式捕获日期。
但这是一个非常具体的案例,我不是regex
专家…
Regex
虽然@WiktorStribiżew已经回答了这个问题,但我建议对正则表达式采取稍微不同的看法…
/(dd?)[._ -]*([a-z]+)[._ -]*(d{4})/i
/ : Pattern delimiter
(dd?) : Matches the day (1 or 2 numbers) and assigns to a capture group
[._ -]* : Mathces a delimiter 0 or more times
([a-z]+) : Matches the textual month and assigns to a capture group
[._ -]* : Mathces a delimiter 0 or more times
(d{4}) : Matches the year (4 numbers) and assigns to a capture group
/ : Pattern delimiter
i : Makes the regex case insensitive, just in case
…这样更容易阅读和理解。当涉及到日期分隔符(或缺少日期分隔符)时,它也稍微更具体一些,因此您不太可能发生冲突。
代码范例$months = [
"gennaio" => "1",
"febbraio" => "2",
"marzo" => "3",
"aprile" => "4",
"maggio" => "5",
"giugno" => "6",
"luglio" => "7",
"agosto" => "8",
"settembre" => "9",
"ottobre" => "10",
"novembre" => "11",
"dicembre" => "12",
];
$titles = [
"Nota_382_del_16 marzo_2016.pdf",
"OCDPC 382 del 16_agosto_2016.pdf",
"OCDPC_382_del 16 _agosto 2016.pdf",
"OCDPC_382_dal 16agosto 2016.pdf",
"OCDPC_382 dall 16luglio2016.pdf",
"OCDPC_382 da 16agosto_2016.pdf",
"OCDPC_382_del_16_settembre 2016.pdf",
"OCDPC_382 di 16 _agosto.2016.pdf",
"OCDPC_382_del-16-agosto 2016.pdf",
"Dipartimento OCDPC 382_del-16-agosto-2016.pdf",
"OCDPC_382 dall'16-febbraio-2016.pdf",
"OCDPC_382 dal'16-agosto-2016 - Dipartimentocivile.pdf",
];
foreach ($titles as $title) {
preg_match('/(dd?)[._ -]*([a-z]+)[._ -]*(d{4})/i', $title, $dateParts);
echo $dateParts[1], "/", $months[strtolower($dateParts[2])], "/", $dateParts[3], " ", PHP_EOL ;
}
/* Potentially easier to read version:
foreach($titles as $title){
preg_match('/(dd?)[._ -]*([a-z]+)[._ -]*(d{4})/i', $title, $dateParts);
list(, $day, $month, $year) = $dateParts;
$month = $months[strtolower($month)];
echo "$day/$month/$year", PHP_EOL;
}
*/
输出:
16/3/2016
16/8/2016
16/8/2016
16/8/2016
16/7/2016
16/8/2016
16/9/2016
16/8/2016
16/8/2016
16/8/2016
16/2/2016
16/8/2016
可以使用
(?<!d)d{1,2}[W_]*p{L}+[W_]*d{4}(?!d)
(?<!d)(d{1,2})[W_]*(p{L}+)[W_]*(d{4})(?!d) // With numbered groups
(?<!d)(?P<day>d{1,2})[W_]*(?P<month>p{L}+)[W_]*(?P<year>d{4})(?!d) // With named groups
参见regex演示。细节:
(?<!d)
-当前位置的左边不允许有数字d{1,2}
-一个或两个数字[W_]*
-零个或多个非字母数字字符p{L}+
-一个或多个Unicode字母[W_]*
- 0个或多个非字母数字字符d{4}
—四位数字(如果年份可以是两位数字,可以使用d{2}(?:d{2})?
)(?!d)
-当前位置的右边不允许有数字。
在PHP中,你可以像这样使用
if (preg_match('~(?<!d)(?P<day>d{1,2})[W_]*(?P<month>p{L}+)[W_]*(?P<year>d{4})(?!d)~u', $string, $match)) {
echo $match["day"] . PHP_EOL;
echo $match["month"] . PHP_EOL;
echo $match["year"];
}
查看PHP演示