Учимся использовать регулярные выражения для исправления кода в 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'',
Комментарии 0