0

文件名:

forms.it.yml
validators.en.xliff

我需要提取三个部分(从文件名)<domain>.<locale>.<format>:,所以我最终得到了这个正则表达式:

/^(?P<domain>\.+).(?P<locale>\w{2,}).(?P<format>\w+)$/

但当然它不起作用。应该有一些明显的东西我错过了。

$match = '/^(?P<domain>\.+).(?P<locale>\w{2,}).(?P<format>\w+)$/';
$subject = 'forms.it.yml';

var_dump(preg_match($match, $subject)); // 0
4

2 回答 2

1

点在您的图案中很特别。通过放入方括号或斜线来使其不特殊。所以点是逐字的点。

当您已经对第一个点执行此操作时,您也需要更改它,但我建议您将其从模式中排除以匹配,否则 - 如果贪婪 - 这可能效果不佳。默认情况下它通常是贪婪的。

/^(?P<domain>[^.]+)\.(?P<locale>[a-zA-Z]{2,})\.(?P<format>\w+)$/
             ##### ^^           ########     ^^
               ^   dot              ^        dot
               |                    |
            not dot      just a little variation

示例/演示

<?php
/**
 * @link http://stackoverflow.com/a/18546468/367456
 */

$match = '/^(?P<domain>[^.]+)\\.(?P<locale>[a-zA-Z]{2,})\\.(?P<format>\\w+)$/';
$subject = 'forms.it.yml';

var_dump(preg_match($match, $subject)); // int(1)

程序输出:

int(1)

使用所有格量词可以进一步优化:

/^(?P<domain>[^.]++)\.(?P<locale>[a-zA-Z]{2,}+)\.(?P<format>\w++)$/
                  ^                          ^                 ^
于 2013-08-31T09:12:31.050 回答
0

您似乎已经逃脱了第一个点,而不是中间点。

您的第一组 ( domain) 正在匹配\.+,它贪婪地匹配一个或多个文字点。

中间模式.是一个正则表达式点,因此匹配所有内容。

您想使用否定字符类将转义点更改为非点模式。我还建议您使用所有格量词来加速不匹配文本的失败:

^(?P<domain>[^.]++)\.(?P<locale>[^.]{2,}+)\.(?P<format>.*+)$
于 2013-08-31T09:17:41.930 回答