0

我有一些文件要使用 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$)/';

预期回报: one.txt

意外返回: one.txt one-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”开头的匹配项,返回:one_1.txt, one_2.txt
  2. 查找以“one-aaa”开头的匹配项,返回:one-aaa_1.txt、one-aaa_2.txt 等

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

谢谢

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

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

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

更新3: 哎呀,我说得太早了。它没有用,但是当我更改键|值对时,键以某种方式被重置,这就是为什么我失去了双重包含的原因。对不起,上面还是不行。

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

谢谢

4

1 回答 1

1

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

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

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

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

编辑:

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

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

这意味着在关键字之后可能会出现一个下划线和一个数字。

于 2012-05-01T08:15:52.727 回答