Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
MultiStringReplacer
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
2 / 2
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 searchAndReplace
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2/**
3 * Copyright 2015 Ori Livneh <ori@wikimedia.org>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * @file
18 * @author Ori Livneh <ori@wikimedia.org>
19 */
20
21namespace AhoCorasick;
22
23/**
24 * Search and replace functionality.
25 */
26class MultiStringReplacer extends MultiStringMatcher {
27
28    /** @var array Mapping of states to outputs. */
29    protected $replacePairs = [];
30
31    /**
32     * Constructor.
33     *
34     * @param array $replacePairs array of ( 'from' => 'to' ) replacement pairs.
35     */
36    public function __construct( array $replacePairs ) {
37        foreach ( $replacePairs as $keyword => $replacement ) {
38            if ( $keyword !== '' ) {
39                $this->replacePairs[$keyword] = $replacement;
40            }
41        }
42        parent::__construct( array_keys( $this->replacePairs ) );
43    }
44
45    /**
46     * Search and replace a set of keywords in some text.
47     *
48     * @param string $text The string to search in.
49     * @return string The input text with replacements.
50     *
51     * @par Example:
52     * @code
53     *   $replacer = new MultiStringReplacer( array( 'csh' => 'sea shells' ) );
54     *   $replacer->searchAndReplace( 'She sells csh by the sea shore.' );
55     *   // result: 'She sells sea shells by the sea shore.'
56     * @endcode
57     */
58    public function searchAndReplace( $text ) {
59        $state = 0;
60        $length = strlen( $text );
61        $matches = [];
62        for ( $i = 0; $i < $length; $i++ ) {
63            $ch = $text[$i];
64            $state = $this->nextState( $state, $ch );
65            foreach ( $this->outputs[$state] as $match ) {
66                $offset = $i - $this->searchKeywords[$match] + 1;
67                $matches[$offset] = $match;
68            }
69        }
70        ksort( $matches );
71
72        $buf = '';
73        $lastInsert = 0;
74        foreach ( $matches as $offset => $match ) {
75            if ( $offset >= $lastInsert ) {
76                $buf .= substr( $text, $lastInsert, $offset - $lastInsert );
77                $buf .= $this->replacePairs[$match];
78                $lastInsert = $offset + $this->searchKeywords[$match];
79            }
80        }
81        $buf .= substr( $text, $lastInsert );
82
83        return $buf;
84    }
85}