preg_replace用于排除指定单词集的模板


preg_replace for a template which excludes the specified set of words

我需要通过在文本文件更改变量类型前面加上指定的命名空间来转换它们。但是我需要跳过基本类型,例如arraystring

所以文本

/**
 * @param ParamType $param
 * @return ReturnType
 */
public function SomeFunction(ParamType $param) {
   ...
}
/**
 * @param array $param
 * @return string
 */
public function OtherFunction($param) {
   ...
}

应转换为

/**
 * @param 'My'Namespace'ParamType $param
 * @return 'My'Namespace'ReturnType
 */
public function SomeFunction('My'Namespace'ParamType $param) {
   ...
}
/**
 * @param array $param
 * @return string
 */
public function OtherFunction($param) {
   ...
}

我的转换现在看起来如下

$classFileText = preg_replace(
    [
        '/@param's+([A-Za-z]+)'s+'$('w+)/',
        '/@return's+([A-Za-z]+)/',
        '/@var's+([A-Za-z]+)/',
        '/'s+function's+([A-Za-z]+)'s*'('s*([A-Za-z]+)'s+'$('w+)/',
    ],
    [
        '@param ''' . $typesNamespace . '''''$1 $''2 ',
        '@return ''' . $typesNamespace . '''''$1',
        '@var ''' . $typesNamespace . '''''$1',
        ' function $1(''' . $typesNamespace . '''''$2 $''3',
    ],
    $classFileText
);

这是可行的,但基类型与其他类型一样是预先准备好的。

我试着用这个技巧来解决这个问题:正则表达式匹配一个不匹配的行;不包含一个单词吗?

还有许多其他。。。但我失败了。

p.s.我遇到了这个问题,将WSDL模式转换为一组类来访问SOAP服务

感谢@bwoebi在评论中给出的答案!

现在运行良好:

$classFileText = preg_replace(
    [
        '/@param's+(?!(?:array|string)'s)([A-Za-z]+)'s+'$('w+)/',
        '/@return's+(?!(?:array|string)'s)([A-Za-z]+)/',
        '/@var's+(?!(?:array|string)'s)([A-Za-z]+)/',
        '/'s+function's+([A-Za-z]+)'s*'('s*(?!(?:array|string)'s)([A-Za-z]+)'s+'$('w+)/',
    ],
    [
        '@param ''' . $typesNamespace . '''''$1 '$$2 ',
        '@return ''' . $typesNamespace . '''''$1',
        '@var ''' . $typesNamespace . '''''$1',
        ' function $1(''' . $typesNamespace . '''''$2 '$$3',
    ],
    $classFileText
);

如果有人能解释一下它是如何工作的,我将不胜感激)