Parse an array of diacritics rules.

@param array $diacritics_rules The rules ( $word => $replacement ).
@param array $patterns         Resulting patterns. Passed by reference.
@param array $replacements     Resulting replacements. Passed by reference.
555433
private function parse_diacritics_rules( array $diacritics_rules, array &$patterns, array &$replacements ) {

		foreach ( $diacritics_rules as $needle => $replacement ) {
			$patterns[]              = '/\b(?<!\w[' . U::NO_BREAK_SPACE . U::SOFT_HYPHEN . '])' . $needle . '\b(?![' . U::NO_BREAK_SPACE . U::SOFT_HYPHEN . ']\w)/u';
			$replacements[ $needle ] = $replacement;
		}
	}
500197
protected function parseRule( $rules )
	{
		if ( is_array( $rules ) )
		{
			$rules = $this->parseArrayRule( $rules );
		}
		else
		{
			$rules = $this->parseStringRule( $rules );
		}

		$rules[0] = $this->normalizeRule( $rules[0] );

		return $rules;
	}
263134
private function applyTransformRule(string $text, string $rule, string $locale, string $regex): string
	{
		$transliterator = $this->getTransliterator($rule, $locale);
		$newText = '';
		$offset = 0;

		foreach ($this->getRanges($text, $regex) as $range) {
			$newText .= substr($text, $offset, $range[0] - $offset);
			$newText .= $this->transformWithContext($transliterator, $text, $range[0], $range[1]);
			$offset = $range[0] + $range[1];
		}

		$newText .= substr($text, $offset);

		return $newText;
	}
853036
protected List<Rule> parsePattern() {
		final DateFormatSymbols symbols = new DateFormatSymbols(locale);
		final List<Rule> rules = new ArrayList<>();

		final String[] ERAs = symbols.getEras();
		final String[] months = symbols.getMonths();
		final String[] shortMonths = symbols.getShortMonths();
		final String[] weekdays = symbols.getWeekdays();
		final String[] shortWeekdays = symbols.getShortWeekdays();
		final String[] AmPmStrings = symbols.getAmPmStrings();

		final int length = pattern.length();
		final int[] indexRef = new int[1];

		for (int i = 0; i < length; i++) {
			indexRef[0] = i;
			final String token = parseToken(pattern, indexRef);
			i = indexRef[0];

			final int tokenLen = token.length();
			if (tokenLen == 0) {
				break;
			}

			Rule rule;
			final char c = token.charAt(0);

			switch (c) {
				case 'G': // era designator (text)
					rule = new TextField(Calendar.ERA, ERAs);
					break;
				case 'y': // year (number)
				case 'Y': // week year
					if (tokenLen == 2) {
						rule = TwoDigitYearField.INSTANCE;
					} else {
						rule = selectNumberRule(Calendar.YEAR, tokenLen < 4 ? 4 : tokenLen);
					}
					if (c == 'Y') {
						rule = new WeekYear((NumberRule) rule);
					}
					break;
				case 'M': // month in year (text and number)
					if (tokenLen >= 4) {
						rule = new TextField(Calendar.MONTH, months);
					} else if (tokenLen == 3) {
						rule = new TextField(Calendar.MONTH, shortMonths);
					} else if (tokenLen == 2) {
						rule = TwoDigitMonthField.INSTANCE;
					} else {
						rule = UnpaddedMonthField.INSTANCE;
					}
					break;
				case 'd': // day in month (number)
					rule = selectNumberRule(Calendar.DAY_OF_MONTH, tokenLen);
					break;
				case 'h': // hour in am/pm (number, 1..12)
					rule = new TwelveHourField(selectNumberRule(Calendar.HOUR, tokenLen));
					break;
				case 'H': // hour in day (number, 0..23)
					rule = selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen);
					break;
				case 'm': // minute in hour (number)
					rule = selectNumberRule(Calendar.MINUTE, tokenLen);
					break;
				case 's': // second in minute (number)
					rule = selectNumberRule(Calendar.SECOND, tokenLen);
					break;
				case 'S': // millisecond (number)
					rule = selectNumberRule(Calendar.MILLISECOND, tokenLen);
					break;
				case 'E': // day in week (text)
					rule = new TextField(Calendar.DAY_OF_WEEK, tokenLen < 4 ? shortWeekdays : weekdays);
					break;
				case 'u': // day in week (number)
					rule = new DayInWeekField(selectNumberRule(Calendar.DAY_OF_WEEK, tokenLen));
					break;
				case 'D': // day in year (number)
					rule = selectNumberRule(Calendar.DAY_OF_YEAR, tokenLen);
					break;
				case 'F': // day of week in month (number)
					rule = selectNumberRule(Calendar.DAY_OF_WEEK_IN_MONTH, tokenLen);
					break;
				case 'w': // week in year (number)
					rule = selectNumberRule(Calendar.WEEK_OF_YEAR, tokenLen);
					break;
				case 'W': // week in month (number)
					rule = selectNumberRule(Calendar.WEEK_OF_MONTH, tokenLen);
					break;
				case 'a': // am/pm marker (text)
					rule = new TextField(Calendar.AM_PM, AmPmStrings);
					break;
				case 'k': // hour in day (1..24)
					rule = new TwentyFourHourField(selectNumberRule(Calendar.HOUR_OF_DAY, tokenLen));
					break;
				case 'K': // hour in am/pm (0..11)
					rule = selectNumberRule(Calendar.HOUR, tokenLen);
					break;
				case 'X': // ISO 8601
					rule = Iso8601_Rule.getRule(tokenLen);
					break;
				case 'z': // time zone (text)
					if (tokenLen >= 4) {
						rule = new TimeZoneNameRule(timeZone, locale, TimeZone.LONG);
					} else {
						rule = new TimeZoneNameRule(timeZone, locale, TimeZone.SHORT);
					}
					break;
				case 'Z': // time zone (value)
					if (tokenLen == 1) {
						rule = TimeZoneNumberRule.INSTANCE_NO_COLON;
					} else if (tokenLen == 2) {
						rule = Iso8601_Rule.ISO8601_HOURS_COLON_MINUTES;
					} else {
						rule = TimeZoneNumberRule.INSTANCE_COLON;
					}
					break;
				case '\'': // literal text
					final String sub = token.substring(1);
					if (sub.length() == 1) {
						rule = new CharacterLiteral(sub.charAt(0));
					} else {
						rule = new StringLiteral(sub);
					}
					break;
				default:
					throw new IllegalArgumentException("Illegal pattern component: " + token);
			}

			rules.add(rule);
		}

		return rules;
	}
1338720
protected function explodeRules($rules)
    {
        foreach ($rules as $key => $rule) {
            $rules[$key] = is_string($rule) ? explode('|', $rule) : $rule;
        }

        return $rules;
    }
1070904
public function setTransliterationReplacements($replacements)
        {
            if(!is_array($replacements)) {
                throw new \Thin\Exception(__METHOD__ . ': method expects a keyed array as argument.', 500);
            }
            foreach($replacements as $key => $value) {
                $this->transliteration[$key] = $value;
            }
            return $this;
        }
1178795
protected function parse_string_rules( $rules ) {
		$split_rules = explode( '|', $rules );
		$parse_rules = [];

		foreach ( $split_rules as $rule ) {
			$parameters = [];

			// Format rule and parameters follows {rule}:{parameters}.
			if ( strpos( $rule, ':' ) !== false ) {
				list( $rule, $parameter ) = explode( ':', $rule, 2 );

				$parameter = false !== strpos( $parameter, ',' )
					? str_getcsv( $parameter )
					: [ $parameter ];

				$parameters = $this->wrap_parameters( $rule, $parameter );
			}

			$parse_rules[] = [ $this->normalize( $rule ), $parameters ];
		}

		return $parse_rules;
	}
75478
protected function parseRuleString($ruleString)
    {
        if (is_string($ruleString)) {
            // Parse for @charset rule
            if (preg_match('/^@charset\s+(["\'])([-a-zA-Z0-9_]+)\g{1}/i', rtrim($ruleString), $matches)) {
                $this->setValue($matches[2]);
            } else {
                throw new \InvalidArgumentException("Invalid format for @charset rule.");
            }
        } else {
            throw new \InvalidArgumentException(
                "Invalid type '" . gettype($ruleString) . "' for argument 'ruleString' given. String expected."
            );
        }
    }
221209
function parse_rule() {
		$rule = trim( $this->rule ) ;

		/* If this is a regex end-token, just mark it and return */
		if ( substr( $rule, 0, 1 ) == '/' ) {
			$this->parsed = new TokenRegex( $rule ) ;
		}
		else {
			$tokens = array() ;
			$this->tokenize( $rule, $tokens ) ;
			$this->parsed = ( count( $tokens ) == 1 ? array_pop( $tokens ) : new TokenSequence( $tokens ) ) ;
		}
		
	}
1187399
public function gsub($pattern, $replacement)
    {
        $pattern = new self($pattern);

        if ($pattern->isRegexp()) {
            return new self(preg_replace($pattern, $replacement, $this));
        } else {
            return new self(str_replace($pattern, $replacement, $this));
        }
    }
408683
public function strOverride($matches)
    {
        $this->pos($this->pos() + strlen($matches[0]));

        $this->record($matches[0], 'DELIMITER');

        $f = $matches[1];

        $type = 'STRING';
        if ($f === 'm' || $f === 'qr' || $f === 's' || $f === 'tr' || $f === 'y') {
            $type = 'REGEX';
        } elseif ($f === 'qw') {
            $type = 'SPLIT_STRING';
        }

        $this->consumeString($matches[3], $type);
        if ($f === 's' || $f === 'tr' || $f === 'y') {
            // s/tr/y take two strings, e.g. s/something/somethingelse/, so we
            // have to consume the next delimiter (if it exists) and consume the
            // string, again.

            // if delims were balanced, there's a new delimiter right here, e.g.
            // s[something][somethingelse]
            $this->skipWhitespace();
            $balanced = Utils::balanceDelimiter($matches[3]) !== $matches[3];
            if ($balanced) {
                $delim2 = $this->scan('/[^a-zA-Z0-9]/');
                if ($delim2 !== null) {
                    $this->record($delim2, 'DELIMITER');
                    $this->consumeString($delim2, 'STRING');
                }
            } else {
                // if they weren't balanced then the delimiter is the same, and has
                // already been consumed as the end-delim to the first pattern
                $this->consumeString($matches[3], 'STRING');
            }
        }
        if ($type === 'REGEX' && $this->scan('/[cgimosxpe]+/')) {
            $this->record($this->match(), 'KEYWORD');
        }
    }
634044
public function rules($rules, $method = '*', array $option = [], array $pattern = [])
    {
        $this->group->addRules($rules, $method, $option, $pattern);
    }
647091
public function setWriteTranslations(array $replacements)
    {
        foreach ($this->translations as $search => $replace) {
            if (!isset($replacements[$search])) {
                $this->removeFilter($search);
                unset($this->translations[$search]);
            }
        }

        foreach ($replacements as $search => $replace) {
            if (!isset($this->translations[$search])) {
                $this->addFilter(
                    $this->replacementFactory->createFilter($search, $replace), $search
                    );
                $this->translations[$search] = true;
            }
        }
    }
1002632
public function set_diacritic_custom_replacements( $custom_replacements = [] ) {
		if ( ! \is_array( $custom_replacements ) ) {
			$custom_replacements = $this->parse_diacritics_replacement_string( $custom_replacements );
		}

		$this->data['diacriticCustomReplacements'] = self::array_map_assoc(
			function( $key, $replacement ) {
				$key         = \strip_tags( \trim( $key ) );
				$replacement = \strip_tags( \trim( $replacement ) );

				if ( ! empty( $key ) && ! empty( $replacement ) ) {
					return [ $key => $replacement ];
				} else {
					return [];
				}
			},
			$custom_replacements
		);

		$this->update_diacritics_replacement_arrays();
	}
1345985
protected function parseStub( $stub, $replacements = [] )
	{
		$output = $stub;

		foreach ( $replacements as $key => $replacement )
		{
			$search = '{{' . $key . '}}';
			$output = str_replace( $search, $replacement, $output );
		}

		return $output;
	}
608148
function(tokens) {
            	if(typeof tokens === "string") {
            		tokens = [tokens];
            	}
                    var results = [];
            	var rule_count = rules$3.length;
            	var num_tokens = tokens.length;
                    var i, token, r, rule;
                
                    for (i = 0; i < num_tokens; i++) {
                        token = tokens[i];
                        // Check the conversion table
                        if (conversionTable[token.toLowerCase()]) {
                            results = results.concat(conversionTable[token.toLowerCase()].split(/\W+/));
                        }
                        
                        // Apply the rules
                        else {
                            var matched = false;
                            for ( r = 0; r < rule_count; r++) {
                                rule = rules$3[r];
                                if (token.match(rule.regex)) {
                                    results = results.concat(token.replace(rule.regex, rule.output).split(/\W+/));
                                    matched = true;
                                    break;
                                }
                            }
                            if (!matched) {
                                results.push(token);
                            }
                        }
                    }

            	return results;
            }
1047154
public function setVarRegexes(array $regexes)
    {
        foreach ($regexes as $varName => $regex) {
            $this->setVarRegex($varName, $regex);
        }
    }