PhpStorm - используем регулярные выражения для правок кода

Учимся использовать регулярные выражения для исправления кода в PhpStorm.

Одну библиотеку, которую я писал, которая была покрыта тестами почти на 100% подверглась рефакторингу (оптимизации). Как результат, 450 тестов сигнатур, (450 юнит тестов!!!), которые раньше проходили на "УРА", стали падать. Изменения затронули только пару абстрактных классов, но тесты были явно привязаны к старому функционалу. Чтобы тесты снова заработали, нужно было исправить 450 php файлов c тестами.

После исправления 10-20 классов ручками, я понял, что ручками это делать будет очень-очень долго и мозго-выносяще.

На помощь пришли регулярные выражения. Сначала я подбирал паттерн поиска в PHPStorm (Ctrl+Shift+F), искал, и оценивал те ли результаты я ожидал найти, а затем (Ctrl+Shift+R) выполнял замену. Конечно, после замены отступы в коде не соответствовали правильному code style. Но Code -> Reformat Code ... в PHPstorm быстро всё поправил.

Некоторые регулярные выражения простые, а некоторые с первого взгляда суровые:

1)
Text to find:  
'@?file_get_contents\(__DIR__ . '/../../(.*.html)'\);'
Replace with: 
'\\$this->getBody('$1');'
2)
Text to find:
'public function testCheckNot(\w*)\(\)\s*\{\s*\$signature = \$this->getSignature\(\);\s*\$body = \$this->getBody\((.*)\)[^}]+}'
Replace width:
'public function testCheckNot$1() \{ \\$res = \\$this->check('http://url', array(), $2); \\$this->assertFalse(\\$res); \}'

Эта регулярка (№2) методы такого типа:

public function testCheckNotBigcommerce()
{
    $signature = $this->getSignature();
    $body = $this->getBody('CMS/BigCommerce.html');
    $response = new Http_Response($body);
    $request = new Http_Request(array(), array(), array(), array());
    $request->setUrl(new Http_Url('http://url'));
    $response->setRequest($request);
    $res = $signature->check($response);
    $this->assertFalse($res);
}

Приводила к таким:

public function testCheckNotBigcommerce()
{
    $res = $this->check('http://url', array(), 'CMS/BigCommerce.html');
    $this->assertFalse($res);
}
3)
Text to find:
'\$body = \$this->getBody\(('.*')\);\s*\$res = \$signature->checkMeta\(\$body\);'
Replace with:
'\\$body = \\$this->getBody($1); \\$metaValues = \\$this->getMetaValues(\\$body); \\$res = \\$signature->checkMeta(\\$metaValues);'
4)
Text to find:
'\$body = \$this->getBody\(('.*')\);\s*\$res = \$signature->checkScript\(\$body\);'
Replace with:
'\\$body = \\$this->getBody($1); \\$scriptLinks = \\$this->getScriptLinks(\\$body); \\$res = \\$signature->checkScript(\\$scriptLinks);'
5)
Text to find:
'\$signature = \$this->getSignature\(\);\s*\$body = \$this->getBody\((.*)\);[^}]*\$res = \$signatur
e->check\(\$response\);'
Replace with:
'\\$res = \\$this->check('http://url', array(), $1);'

Удаление конкретного метода целиком, и, коммента перед ним (если коммент есть):

6)
Text to find:
'(\/\*\*[^/]*\*\/)?\s*(protected|private) function getSignature\(\)\s*\{[^}]*\}[^}]*}'
Replace with:
'' #заменяем на пустую строку
7)
Text to find:
'\$this->assertTrue\(\$signature->checkMeta\(\$body\)\);'
Replace with:
'\\$metaValues = \\$this->getMetaValues(\\$body); \\$res = \\$signature->checkMeta(\\$metaValues); \\$this->assertTrue(\\$res);'
8)
Text to find:
'\$res = \$this->getSignature\(\)->checkScript\(\$body\);'
Replace with:
'\\$scriptLinks = \\$this->getScriptLinks(\\$body); \\$res = \\$this->getSignature()->checkScript(\\$scriptLinks);'

Изменить имена классов, добавить префикс перед именем класса, от которого наследуемся. PHPStorm регулярка для переименования имён классов может выглядеть так:

Text to find: 'extends (\w+)'
Raplace with: 'extends Prefix_$1'

Text to find: 'class (\w+)'
Raplace with: 'class Prefix_$1'

Как видно из примеров, спецсимволы (например: (, ), $, ?) нужно экранировать символом '\'. В выражении для поиска те части, что в скобках, будут заматчены и сохранены в переменные $1, $2, $3 и т.д. в порядке появления. Чтобы в строке для замены (Replace with) написать переменную (например, $this->param), нужно выполнить экранирование 2 раза. Т.о. то, что мы найдём заменится на строку $this->param:

Raplace with: \\$this->param

В строке для поиска (регулярном выражении, Text to find) для того, чтобы, например найти эту же строку, экранирование нужно выполнить 1 раз:

Text to find: \$this->param

Обернуть строки в кавычки и поставить запятые в конце строк (напр, если нужно сформировать массив из скопированных строк, все строки разные, но начинаются на mozilla):

Text to find: '(mozilla.*)'
Replace with: ''$1'',

 

 
Поисковые запросы, по которым приходили пользователи
 
 
 
 

icon Комментарии 0

Ваш комментарий к статье.. (для авторизованных)

ctrl+enter

icon Вход в систему

зарегистрироваться
НОВЫЕ ПОЛЬЗОВАТЕЛИ