From 2e10be1cd604944bda2695243c0ce0cfc2a4faa0 Mon Sep 17 00:00:00 2001 From: Iman Date: Mon, 27 Jan 2025 01:25:27 +0330 Subject: [PATCH] ignore whitespace feature --- README.md | 4 ++-- src/Finder.php | 23 ++++++++++++++--------- src/Keywords/BlackSpace.php | 22 ++++++++++++++++++++++ src/PatternParser.php | 12 +++++++----- src/Searcher.php | 3 ++- 5 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 src/Keywords/BlackSpace.php diff --git a/README.md b/README.md index d805f39..2d61b5e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # Php Smart Search/replace Functionality [![tests](https://github.com/imanghafoori1/php-smart-search-replace/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/imanghafoori1/php-smart-search-replace/actions/workflows/tests.yml) -[![Coverage Status](https://coveralls.io/repos/github/imanghafoori1/php-smart-search-replace/badge.svg?branch=main)](https://coveralls.io/github/imanghafoori1/php-smart-search-replace?branch=main) [![Total Downloads](https://img.shields.io/packagist/dt/imanghafoori/php-search-replace.svg?style=flat-square)](https://packagist.org/packages/imanghafoori/php-search-replace) [![Latest Stable Version](https://poser.pugx.org/imanghafoori/php-search-replace/v/stable?format=flat-square)](https://packagist.org/packages/imanghafoori/php-search-replace) -[![Check Imports](https://github.com/imanghafoori1/php-smart-search-replace/actions/workflows/imports.yml/badge.svg?branch=main)](https://github.com/imanghafoori1/php-smart-search-replace/actions/workflows/imports.yml) [![MIT Licensed](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md) +[![Check Imports](https://github.com/imanghafoori1/php-smart-search-replace/actions/workflows/imports.yml/badge.svg?branch=main)](https://github.com/imanghafoori1/php-smart-search-replace/actions/workflows/imports.yml) ## It is much easier than using regex. @@ -49,6 +48,7 @@ Here is a copmerehensive list of placeholders you can use: - ``: to capture a whole php statement. - `""` or ``: for method or function names. `->where` or `::where` - ``: for whitespace blocks +- ``: for non-whitespace - `` or `''`: for true or false (acts case-insensetive) - ``: for numeric values - ``: for type-casts like: `(array) $a;` diff --git a/src/Finder.php b/src/Finder.php index ff6d88d..083ca9d 100644 --- a/src/Finder.php +++ b/src/Finder.php @@ -2,8 +2,6 @@ namespace Imanghafoori\SearchReplace; -use Imanghafoori\SearchReplace\Keywords; - class Finder { public static $primitiveTokens = [ @@ -31,6 +29,7 @@ class Finder Keywords\Name::class, Keywords\DocBlock::class, Keywords\WhiteSpace::class, + Keywords\BlackSpace::class, Keywords\Comment::class, Keywords\MethodVisibility::class, Keywords\Boolean::class, @@ -50,7 +49,7 @@ class Finder //',' => ',', ]; - public static function compareTokens($pattern, $tokens, $startFrom, $namedPatterns = []) + public static function compareTokens($pattern, $tokens, $startFrom, $namedPatterns = [], $ignoreWhitespace = true) { $pi = $j = 0; $tCount = count($tokens); @@ -73,10 +72,15 @@ public static function compareTokens($pattern, $tokens, $startFrom, $namedPatter return false; } - [$pToken, $j] = self::getNextToken($pattern, $j); + [$pToken, $j] = self::getNextToken($pattern, $j, $ignoreWhitespace ? null : T_WHITESPACE); $pi = $startFrom; - [, $startFrom] = self::forwardToNextToken($pToken, $tokens, $startFrom); + + if ($ignoreWhitespace) { + [, $startFrom] = self::forwardToNextToken($pToken, $tokens, $startFrom); + } else { + [, $startFrom] = self::getNextToken($tokens, $startFrom, T_WHITESPACE); + } } if ($pCount === $j) { @@ -187,7 +191,8 @@ public static function getMatches( $namedPatterns = [], $filters = [], $startFrom = 1, - $maxMatch = null + $maxMatch = null, + $ignoreWhitespace = true ) { $pIndex = PatternParser::firstNonOptionalPlaceholder($patternTokens); $optionalStartingTokens = array_slice($patternTokens, 0, $pIndex); @@ -199,7 +204,7 @@ public static function getMatches( while ($i < $allCount) { $restPatternTokens = array_slice($patternTokens, $pIndex); - $isMatch = self::compareTokens($restPatternTokens, $tokens, $i, $namedPatterns); + $isMatch = self::compareTokens($restPatternTokens, $tokens, $i, $namedPatterns, $ignoreWhitespace); if (! $isMatch) { $i++; continue; @@ -243,7 +248,7 @@ public static function compareIt($tToken, int $type, $token, &$i) private static function forwardToNextToken($pToken, $tokens, $startFrom) { - if (isset($pToken[1]) && self::is($pToken, '')) { + if (isset($pToken[1]) && (self::is($pToken, ['', '']))) { return self::getNextToken($tokens, $startFrom, T_WHITESPACE); } elseif (isset($pToken[1]) && self::is($pToken, '')) { return self::getNextToken($tokens, $startFrom, T_COMMENT); @@ -295,7 +300,7 @@ private static function optionalStartingTokens($optionalStartingTokens, $tokens, public static function extractValue($matches, $first = '') { $segments = [$first]; - + foreach ($matches as $match) { $segments[] = $match[0][1]; } diff --git a/src/Keywords/BlackSpace.php b/src/Keywords/BlackSpace.php new file mode 100644 index 0000000..aa0f7c0 --- /dev/null +++ b/src/Keywords/BlackSpace.php @@ -0,0 +1,22 @@ +'; + } + + public static function getValue($tokens, &$startFrom, &$placeholderValues, $pToken) + { + $t = $tokens[$startFrom]; + + if ($t[0] === T_WHITESPACE) { + return false; + } + + $placeholderValues[] = $t; + } +} \ No newline at end of file diff --git a/src/PatternParser.php b/src/PatternParser.php index 96d416c..1207c4e 100644 --- a/src/PatternParser.php +++ b/src/PatternParser.php @@ -14,6 +14,7 @@ private static function getParams($pToken, $id) public static function parsePatterns($patterns, $normalize = true) { $defaults = [ + 'ignore_whitespaces' => true, 'predicate' => null, 'mutator' => null, 'named_patterns' => [], @@ -50,7 +51,7 @@ public static function tokenize($pattern) private static function cleanComments($pattern) { - foreach (['"', "'", ''] as $c) { + foreach (['"', "'"] as $c) { for ($i = 1; $i !== 11; $i++) { $pattern = str_replace("$c<$i:", "$c<", $pattern, $count); } @@ -133,6 +134,7 @@ private static function getSearchPatterns() { $names = implode(',', [ 'white_space', + 'not_whitespace', 'string', 'str', 'variable', @@ -156,10 +158,10 @@ private static function getSearchPatterns() 'boolean', ]); - // the order of the patterns matter. return [ - ['search' => '<"">?', 'replace' => '"<"<1>">?"'], - ['search' => '<"">', 'replace' => '"<"<1>">"'], + // the order of the patterns matter. + ['search' => '<"">?', 'replace' => '"<"<1>">?"',], + ['search' => '<"">', 'replace' => '"<"<1>">"',], ]; } @@ -173,7 +175,7 @@ private static function addQuotes(string $search, array $all) private static function normalize($to, $all) { - $to['search'] = self::addQuotes(self::cleanComments($to['search']), $all); + $to['search'] = self::addQuotes($to['search'], $all); is_string($to['replace'] ?? 0) && ($to['replace'] = self::addQuotes( $to['replace'], diff --git a/src/Searcher.php b/src/Searcher.php index ca283c5..0670d53 100644 --- a/src/Searcher.php +++ b/src/Searcher.php @@ -50,7 +50,8 @@ public static function searchReplaceOnePattern($pattern, $tokens, $maxMatches = $pattern['named_patterns'], $pattern['filters'], 1, - $maxMatches + $maxMatches, + $pattern['ignore_whitespaces'] ); [