RegExp:在定界符之前或之后

RegExp: before or after a delimiter

考虑以下

use namespace;

class name impl... {

    use Trait;
}

如果我想从 class 定义之前或之后的定义中提取 use,我该怎么做?好吧,在上面的例子中,它已经足够简单了,但是如果它也应该在两个地方都有多个 use 的实际代码文件上工作,甚至可能没有组合在一起,但中间还有其他东西,还有所有行删除字符?

获取它们很容易,但我希望它在到达 class 时停止或从 class 开始。只是无法接缝让任何东西正常工作。

行、注释和文字已被删除,因此不应考虑这些。

为了检测出现在最外层范围内的 use 子句,您需要删除 {...} 的所有(嵌套)块。您不能在单个表达式中执行此操作(由于深度不受限制),但如果您愿意,可以在循环中应用块删除:

$s = <your code>;
$prev_s = "";
while ($s != $prev_s) {
    $prev_s = $s;
    $s = preg_replace('\{[^}]*\}','',$s);
}

现在您可以收集外部使用条款

$outer_uses = preg_match_all('\buse\s+(\w+)', $s);

删除块还不错,但我需要全部获取它们,包括内部范围内的块,我只需要知道哪个是哪个。

这对于单个 RegExp 来说显然太多了,所以这就是我所做的。以防其他阅读本文的人正在寻找答案。

使用一些东西来定位class声明的偏移起始位置。

/\b(class|interface|trait)\s+[\w]+.*{/s

这与 preg_match 和它的 PREG_OFFSET_CAPTURE 标志相结合将为您提供偏移量。

然后提取所有 use 子句,内部和外部范围。

/\buse\s+(?<full>([\w\\]+(?:\s+as\s+[\w]+)?(?:\s*[,]\s*)?)+)(?:(?<=[\\]){(?<inline>.*)})?\s*[;{]/

将此与 preg_match_all 一起使用,使用 PREG_SET_ORDER|PREG_OFFSET_CAPTURE,这将包括每个匹配项的偏移量。

现在只需将每个偏移量与一开始提取的偏移量进行比较。如果较低,则为参考子句。如果它更高,这是一个特征条款。