【问题标题】:RegExp: before or after a delimiterRegExp:在分隔符之前或之后
【发布时间】:2018-03-20 20:24:08
【问题描述】:

考虑以下

use namespace;

class name impl... {

    use Trait;
}

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

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

行、cmets 和文字已被剥离,因此不应考虑这些。

【问题讨论】:

  • 你说的“extract”是什么意思?如果我们知道您想要完成什么,我们会更容易提供帮助。
  • 试图弄清楚如何从 php 文件中的使用引用中提取类和特征名称。但是要确定哪个是哪个,您必须知道它是从类定义的哪一侧提取的。所以我的尝试是先提取一个,然后再提取另一个。但要做到这一点,我必须让它从定义类的点停止或开始。
  • 避免 $use 很容易,我用其他提取方法来做到这一点。但是,是的,我应该正确地提到我已经使用 RegExp 来停止文件中的所有文字,以使这些搜索更容易。
  • 没有线条,这些线条与 cmets 和文字一起被剥离。

标签: php regex preg-match pcre preg-match-all


【解决方案1】:

为了检测出现在最外层范围内的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);

【讨论】:

    【解决方案2】:

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

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

    使用某物来定位类声明的偏移起始位置。

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

    结合preg_matchPREG_OFFSET_CAPTURE 标志将为您提供偏移量。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-03-13
      • 2021-04-26
      • 2018-06-14
      • 2012-12-21
      • 1970-01-01
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多