PHP preg_match边界内的单词


PHP preg_match words within boundaries

我有一些文件可以使用preg_match扫描模式,例如:

文件名:

(a group: one)
one.txt 
(another group: one-aaa)
one-aaa.txt
one-aaa_1.txt
one-aaa_b.txt
one-aaa_3.txt
one-aaa_whatever.txt
(some other group: one-bbb)
one-bbb.jpg
one-bbb_1.txt
one-bbb_2.txt
one-bbb_t.txt
one-bbb_whatever.txt

该组由名称定义(因此:one,one-aaa,one-bbb是不同的组(,并且仅限于文件.txt。

请不要建议使用不同的目录。这些文件已经分散在某些目录中,我需要一种方法来按关键字而不是目录查找匹配项。

现在我可以通过指定"one"、"one-aaa"等来手动定义组,但在preg_match时遇到问题。我的preg_match将"one"和"one-aaa"作为单个组返回:

$keyword = 'one';
$match = '/(^)' . $keyword . '(.*'.txt$)/';
$match = '/'b(' . $keyword . ')'b(.*'.txt$)/';

预期回报:一.txt

意外退货:一.txt一个 aaa.txt等

更新 1:当关键字更改为"one-aaa"时,我希望它返回:one-aaa.txt,one-aaa_1.txt等。我的分组方式是:

$keyword = str_replace('_', ' ', $file->name);
returns: one, one-aaa, one-bbb, etc

我想用简单的英语说:

  1. 查找以"一"开头的匹配项,返回:one_1.txt,one_2.txt
  2. 查找以"one-aaa"开头的匹配项,返回:1-aaa_1.txt、1-aaa_2.txt等

任何人都可以阐明正确的正则表达式吗?

谢谢

更新 2:这里之前有人提供了避免贪婪正则表达式的建议,并使用 .*?相反,答案被删除了。它最终按照他的建议以这种方式工作:

$match = '/^'b(' . $keyword . ')'b(.*?.txt$)/';

我现在应该为谁分配答案?任何人都可以自愿写出像上面这样的工作答案,或者改进它吗?

更新 3:哎呀,我说得太早了。它不起作用,但是当我更改键|值对时,键以某种方式重置,这就是我忘记双重包含的原因。对不起,以上还是不行。

更新 4:我终于有了附加条件,如果它们与组不匹配,则简单地排除输出。额外的代码和额外的扫描,不好,但至少它现在可以按预期工作。仍然使用上面建议的正则表达式。仍在寻找最终的正则表达式解决方案(如果有的话(。如果否,则"否"应该是所选答案

谢谢

当然 - ".*"允许其他字符进入。 将其更改为:

$keyword = 'one';
$match = '/(^)' . $keyword . '('.txt$)/';
$match = '/'b(' . $keyword . ')'b('.txt$)/';

".*"表示出现 0 次或更多次的任何字符...

编辑:

看到更新后,假设one_10或one_100也可以存在。

你可以试试: $match = '/^' . $keyword . '(_[0-9]+)?'.txt$/';

这意味着在关键字之后可能会有一个带有数字的下划线。