diff --git a/features/search-replace.feature b/features/search-replace.feature index ebcf4587e..d01c25828 100644 --- a/features/search-replace.feature +++ b/features/search-replace.feature @@ -174,6 +174,14 @@ Feature: Do global search/replace Scenario: Regex search/replace with a incorrect `--regex-flags` Given a WP install When I try `wp search-replace '(Hello)\s(world)' '$2, $1' --regex --regex-flags='kppr'` + Then STDERR should contain: + """ + (Hello)\s(world) + """ + And STDERR should contain: + """ + kppr + """ And the return code should be 1 Scenario: Search and replace within theme mods @@ -355,10 +363,21 @@ Feature: Do global search/replace http://example.jp """ + When I run `wp search-replace 'http://example.jp/' 'http://example.com/' wp_options --regex-delimiter='/'` + Then STDOUT should be a table containing rows: + | Table | Column | Replacements | Type | + | wp_options | option_value | 2 | PHP | + + When I run `wp option get home` + Then STDOUT should be: + """ + http://example.com + """ + When I try `wp search-replace 'HTTP://EXAMPLE.COM' 'http://example.jp/' wp_options --regex --regex-flags=i --regex-delimiter='1'` Then STDERR should be: """ - Error: Incorrect regex delimiter. + Error: The regex '1HTTP://EXAMPLE.COM1i' fails. """ And the return code should be 1 diff --git a/src/Search_Replace_Command.php b/src/Search_Replace_Command.php index 270e96da0..6b875ead2 100644 --- a/src/Search_Replace_Command.php +++ b/src/Search_Replace_Command.php @@ -91,7 +91,7 @@ class Search_Replace_Command extends WP_CLI_Command { * : Pass PCRE modifiers to regex search-replace (e.g. 'i' for case-insensitivity). * * [--regex-delimiter=] - * : The delimiter to use for the regex. It must be escaped if it appears in the search string. + * : The delimiter to use for the regex. It must be escaped if it appears in the search string. The default value is the result of `chr(1)`. * * [--format=] * : Render output in a particular format. @@ -139,18 +139,20 @@ public function __invoke( $args, $assoc_args ) { $this->verbose = \WP_CLI\Utils\get_flag_value( $assoc_args, 'verbose' ); $this->regex = \WP_CLI\Utils\get_flag_value( $assoc_args, 'regex' ); $this->regex_flags = \WP_CLI\Utils\get_flag_value( $assoc_args, 'regex-flags' ); - $this->regex_delimiter = \WP_CLI\Utils\get_flag_value( $assoc_args, 'regex-delimiter', '/' ); + $this->regex_delimiter = \WP_CLI\Utils\get_flag_value( $assoc_args, 'regex-delimiter', chr( 1 ) ); $this->format = \WP_CLI\Utils\get_flag_value( $assoc_args, 'format' ); - // http://php.net/manual/en/reference.pcre.pattern.modifiers.php - if ( $this->regex_flags && ! preg_match( '/^(?!.*(.).*\1)[imsxeADSUXJu]+$/', $this->regex_flags ) ) { - WP_CLI::error( "Incorrect PCRE modifiers." ); - } - - if ( empty( $this->regex_delimiter ) ) { - $this->regex_delimiter = '/'; - } elseif( ! preg_match( '/^[^0-9\\s]{1}$/', $this->regex_delimiter ) ) { - WP_CLI::error( "Incorrect regex delimiter." ); + if ( ! empty( $this->regex ) ) { + if ( '' === $this->regex_delimiter ) { + $this->regex_delimiter = chr( 1 ); + } + $search_regex = $this->regex_delimiter; + $search_regex .= $old; + $search_regex .= $this->regex_delimiter; + $search_regex .= $this->regex_flags; + if ( false === @preg_match( $search_regex, '' ) ) { + \WP_CLI::error( "The regex '$search_regex' fails." ); + } } $this->skip_columns = explode( ',', \WP_CLI\Utils\get_flag_value( $assoc_args, 'skip-columns' ) ); diff --git a/src/WP_CLI/SearchReplacer.php b/src/WP_CLI/SearchReplacer.php index 3aaed0e40..e4a508450 100644 --- a/src/WP_CLI/SearchReplacer.php +++ b/src/WP_CLI/SearchReplacer.php @@ -84,7 +84,11 @@ private function _run( $data, $serialised, $recursion_level = 0, $visited_data = else if ( is_string( $data ) ) { if ( $this->regex ) { - $data = preg_replace( "$this->regex_delimiter$this->from$this->regex_delimiter$this->regex_flags", $this->to, $data ); + $search_regex = $this->regex_delimiter; + $search_regex .= $this->from; + $search_regex .= $this->regex_delimiter; + $search_regex .= $this->regex_flags; + $data = preg_replace( $search_regex, $this->to, $data ); } else { $data = str_replace( $this->from, $this->to, $data ); }