preg_match 两种不同(但有些相似)的字符串模式中的任何一种?
preg_match either of two different (but somewhat similar) string patterns?
我正在遍历 PHP 文件名数组以构建匹配两种不同模式的 select 文件列表。
我让它在一种模式或另一种模式上工作,但不能同时使用这两种模式:
foreach ($file_array as $file_link) {
$p = '~(-([a-z]{2})\.pdf(|(-([a-z]{4})\.pdf)~';
preg_match($p, $file_link, $matches);
switch ($matches[1]) {
case 'en':
$link_array[1] = array('English', $file_link);
break;
case 'ja':
$link_array[2] = array('日本語', $file_link);
break;
...
case 'ptbr':
$link_array[13] = array('Português brasileiro', $file_link);
break;
case 'ptpt':
$link_array[14] = array('Português europeu', $file_link);
break;
...
}
...
}
$file_array 中的文件格式为:
- 文件名-en.pdf
- 文件名-ja.pdf
- 文件名-ptbr.pdf
- 文件名-ptpt.pdf
我希望匹配 -([a-z]{2})\.pdf
或 -([a-z]{4})\.pdf
模式。我在上面 $p = '~(-([a-z]{2})\.pdf(|(-([a-z]{4})\.pdf)~';
中缺少什么才能使它正常工作。
此外,是否有更好的方法来解决将文件名更改为另一种格式(我试图避免这种格式)的问题?
我的客户其实想要这种格式的文件,但是好像更麻烦:
- 文件名-pt-br.pdf
- 文件名-pt-pt.pdf
谢谢!
约翰
使用此正则表达式并以非捕获组 (?:-[a-z]{2})?
的形式进行额外检查,该组将捕获 pt-br
:
`-([a-z]{2}(?:-[a-z]{2})?|[a-z]{4})\.pdf`
$p = "~-([a-z]{2}(?:-[a-z]{2})?|[a-z]{4})\.pdf~";
看看demo。
如果您想在单个正则表达式中执行此操作,请尝试类似以下内容(请原谅 %
边界字符,与您的 ~
不同。使用的 x
修饰符允许评论
$regex = '%
- # starting -
( # start grouping parenthesis
[a-z]{2} # a through z repeated twice
| # or
[a-z]{4} # a through z repeated four times
) # end group
\.pdf$ # string ends in .pdf
%x';
此外,虽然正则表达式始终是一项有趣的练习,但不要害怕为每个模式使用一个正则表达式。虽然理论上性能会受到影响,但很可能不会影响您的应用程序。同样,不要害怕为一些更简单的 explode/implodes
避开正则表达式
$parts = explode('.', $filename);
$extension = array_pop($parts);
$full = implode('', $parts);
$parts = explode('-', $full);
$identifier = array_pop($parts);
switch($identifier)
{
case 'en':
break;
//etc...
}
我正在遍历 PHP 文件名数组以构建匹配两种不同模式的 select 文件列表。
我让它在一种模式或另一种模式上工作,但不能同时使用这两种模式:
foreach ($file_array as $file_link) {
$p = '~(-([a-z]{2})\.pdf(|(-([a-z]{4})\.pdf)~';
preg_match($p, $file_link, $matches);
switch ($matches[1]) {
case 'en':
$link_array[1] = array('English', $file_link);
break;
case 'ja':
$link_array[2] = array('日本語', $file_link);
break;
...
case 'ptbr':
$link_array[13] = array('Português brasileiro', $file_link);
break;
case 'ptpt':
$link_array[14] = array('Português europeu', $file_link);
break;
...
}
...
}
$file_array 中的文件格式为:
- 文件名-en.pdf
- 文件名-ja.pdf
- 文件名-ptbr.pdf
- 文件名-ptpt.pdf
我希望匹配 -([a-z]{2})\.pdf
或 -([a-z]{4})\.pdf
模式。我在上面 $p = '~(-([a-z]{2})\.pdf(|(-([a-z]{4})\.pdf)~';
中缺少什么才能使它正常工作。
此外,是否有更好的方法来解决将文件名更改为另一种格式(我试图避免这种格式)的问题?
我的客户其实想要这种格式的文件,但是好像更麻烦:
- 文件名-pt-br.pdf
- 文件名-pt-pt.pdf
谢谢!
约翰
使用此正则表达式并以非捕获组 (?:-[a-z]{2})?
的形式进行额外检查,该组将捕获 pt-br
:
`-([a-z]{2}(?:-[a-z]{2})?|[a-z]{4})\.pdf`
$p = "~-([a-z]{2}(?:-[a-z]{2})?|[a-z]{4})\.pdf~";
看看demo。
如果您想在单个正则表达式中执行此操作,请尝试类似以下内容(请原谅 %
边界字符,与您的 ~
不同。使用的 x
修饰符允许评论
$regex = '%
- # starting -
( # start grouping parenthesis
[a-z]{2} # a through z repeated twice
| # or
[a-z]{4} # a through z repeated four times
) # end group
\.pdf$ # string ends in .pdf
%x';
此外,虽然正则表达式始终是一项有趣的练习,但不要害怕为每个模式使用一个正则表达式。虽然理论上性能会受到影响,但很可能不会影响您的应用程序。同样,不要害怕为一些更简单的 explode/implodes
避开正则表达式$parts = explode('.', $filename);
$extension = array_pop($parts);
$full = implode('', $parts);
$parts = explode('-', $full);
$identifier = array_pop($parts);
switch($identifier)
{
case 'en':
break;
//etc...
}