程序员工具箱

PHP 懒人正则

2023-12-26  本文已影响0人  许一沐

快速 字符串模组取值

/**
     * 快速 字符串模组取值
     *
     * @param $string
     * @param $pattern
     * @param false $lowercase
     * @param null $whitespace
     * @param false $strip_val
     * @return array
     */
    public static function strQuickExtractValues($string, $pattern, $lowercase = false, $whitespace = null, $strip_val = false)
    {
        static $delimiters = ['{', '}'];

        $data = ['string' => $string, 'pattern' => $pattern, 'reg_pattern' => '', 'match' => []];

        $spRe = false;

        if (strpos($string, '/') !== false) {
            foreach (['~', ':', ';', '!', '@'] as $sp) {
                if (strpos($string, $sp) === false) {
                    $spRe = $sp;
                    break;
                }
            }

            $string = str_replace('/', $spRe, $string);
            $pattern = str_replace('/', $spRe, $pattern);
        }

        // Checking for lowercase conversion
        if ($lowercase) {
            $string = strtolower($string);
        }

        // Checking for a sequence in delimiters
        if (!is_array($delimiters) || count($delimiters) != 2) {
            return $data;
        }

        // Check if whitespace should be removed
        if (!is_null($whitespace)) {
            // Make sure it's an integer
            if (!is_int($whitespace)) {
                return $data;
            }

            // Make sure it's a non-negative integer
            if ($whitespace < 0) {
                return $data;
            }

            // Now remove whitespace
            if ($whitespace == 0) {
                // Removing all whitespace from each value
                $string = preg_replace('/\s/', '', $string);
            } else {
                // Removing only extra whitespace from each value
                $string = preg_replace(
                    '/(\s)\s{' . ($whitespace - 1) . ',}/', '\\1', $string
                );
            }
        }

        // Helper regular expressions
        $splitter = '/(' . preg_quote($delimiters[0]) . '\w+' . preg_quote($delimiters[1]) . ')/';
        $extracter = '/' . preg_quote($delimiters[0]) . '(\w+)' . preg_quote($delimiters[1]) . '/';

        // Split pattern into parts including named groups
        $parts = preg_split($splitter, $pattern, -1, PREG_SPLIT_DELIM_CAPTURE);

        // Expand group or escape non-group
        foreach ($parts as &$p) {
            // Part is a named group
            if (preg_match($splitter, $p)) {
                preg_match($extracter, $p, $matches);
                $name = $matches[1];
                $p = '(?P<' . $name . '>.+)';
            } // Part is something else
            else {
                // Escape values with special semantics in regular expressions
                $p = preg_quote($p);
            }
        }
        unset($p);

        // Build expanded pattern
        $data['reg_pattern'] = '/^' . implode('', $parts) . '$/';

        try {
            // Attempt to extract values
            preg_match($data['reg_pattern'], $string, $matches);
            $value_dict = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);

            foreach ($value_dict as $name => &$value) {

                if ($spRe) {
                    $value = str_replace($spRe, '/', $value);
                }

                // Check if values must be stripped
                if ($strip_val) {
                    $value = trim($value);
                }
            }

            // Finally, return values
            $data['match'] = $value_dict;
        } catch (\Exception $e) {
        }

        return $data;
    }


    public static function strQuickExtractValuesTest()
    {
        print_r(self::strQuickExtractValues('/2012/08/12/test.html', '/{year}/{month}/{day}/{title}.html'));
        print_r(self::strQuickExtractValues('\2012\08\12\test.html', '\{year}\{month}\{day}\{title}.html'));
        print_r(self::strQuickExtractValues('John Doe <john@example.com> (http://example.com)', '{name} <{email}> ({url})'));
        print_r(self::strQuickExtractValues('from 4th October  to 10th  October', 'from {from} to {to}'));
        print_r(self::strQuickExtractValues('Convert 1500 Grams to Kilograms', 'convert {quantity} {from_unit} to {to_unit}', True));
        print_r(self::strQuickExtractValues('The time is 4:35pm here at Lima, Peru', 'The time is {time} here at {city}'));
    }
上一篇 下一篇

猜你喜欢

热点阅读