• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dg / texy / 16790351274

06 Aug 2025 10:42PM UTC coverage: 92.746% (+0.005%) from 92.741%
16790351274

push

github

dg
HtmlElement: removed toHtml() & toText()

18 of 19 new or added lines in 5 files covered. (94.74%)

136 existing lines in 23 files now uncovered.

2391 of 2578 relevant lines covered (92.75%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.24
/src/Texy/Regexp.php
1
<?php
2

3
/**
4
 * This file is part of the Texy! (https://texy.info)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Texy;
11

12
use JetBrains\PhpStorm\Language;
13
use function array_keys, array_values, is_array, is_object, preg_last_error, preg_last_error_msg, preg_match, preg_match_all, preg_replace, preg_replace_callback, preg_split, strlen;
14
use const PREG_OFFSET_CAPTURE, PREG_SET_ORDER, PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_OFFSET_CAPTURE;
15

16

17
class Regexp
18
{
19
        /**
20
         * Divides the string into arrays according to the regular expression. Expressions in parentheses will be captured and returned as well.
21
         */
22
        public static function split(
1✔
23
                string $subject,
24
                #[Language('PhpRegExpXTCommentMode')]
25
                string $pattern,
26
                bool $captureOffset = false,
27
                bool $skipEmpty = false,
28
                int $limit = -1,
29
        ): array
30
        {
31
                $flags = ($captureOffset ? PREG_SPLIT_OFFSET_CAPTURE : 0) | ($skipEmpty ? PREG_SPLIT_NO_EMPTY : 0);
1✔
32
                return self::pcre('preg_split', [$pattern . 'ux', $subject, $limit, $flags | PREG_SPLIT_DELIM_CAPTURE]);
1✔
33
        }
34

35

36
        /**
37
         * Searches the string for the part matching the regular expression and returns
38
         * an array with the found expression and individual subexpressions, or `null`.
39
         */
40
        public static function match(
1✔
41
                string $subject,
42
                #[Language('PhpRegExpXTCommentMode')]
43
                string $pattern,
44
                bool $captureOffset = false,
45
                int $offset = 0,
46
        ): ?array
47
        {
48
                $flags = ($captureOffset ? PREG_OFFSET_CAPTURE : 0) | PREG_UNMATCHED_AS_NULL;
1✔
49
                if ($offset > strlen($subject)) {
1✔
UNCOV
50
                        return null;
×
51
                } elseif (!self::pcre('preg_match', [$pattern . 'ux', $subject, &$m, $flags, $offset])) {
1✔
52
                        return null;
1✔
53
                } else {
54
                        return $m;
1✔
55
                }
56
        }
57

58

59
        /**
60
         * Searches the string for all occurrences matching the regular expression and
61
         * returns an array of arrays containing the found expression and each subexpression.
62
         * @return array[]
63
         */
64
        public static function matchAll(
1✔
65
                string $subject,
66
                #[Language('PhpRegExpXTCommentMode')]
67
                string $pattern,
68
                bool $captureOffset = false,
69
                int $offset = 0,
70
        ): array
71
        {
72
                if ($offset > strlen($subject)) {
1✔
UNCOV
73
                        return [];
×
74
                }
75
                $flags = ($captureOffset ? PREG_OFFSET_CAPTURE : 0) | PREG_UNMATCHED_AS_NULL | PREG_SET_ORDER;
1✔
76
                self::pcre('preg_match_all', [$pattern . 'ux', $subject, &$m, $flags, $offset]);
1✔
77
                return $m;
1✔
78
        }
79

80

81
        /**
82
         * Replaces all occurrences matching regular expression $pattern which can be string or array in the form `pattern => replacement`.
83
         */
84
        public static function replace(
1✔
85
                string $subject,
86
                #[Language('PhpRegExpXTCommentMode')]
87
                string|array $pattern,
88
                string|callable $replacement = '',
89
                int $limit = -1,
90
                bool $captureOffset = false,
91
        ): string
92
        {
93
                if (is_object($replacement) || is_array($replacement)) {
1✔
94
                        if (!is_callable($replacement, false, $textual)) {
1✔
UNCOV
95
                                throw new Exception("Callback '$textual' is not callable.");
×
96
                        }
97

98
                        $flags = ($captureOffset ? PREG_OFFSET_CAPTURE : 0) | PREG_UNMATCHED_AS_NULL;
1✔
99
                        return self::pcre('preg_replace_callback', [$pattern . 'ux', $replacement, $subject, $limit, 0, $flags]);
1✔
100

101
                } elseif (is_array($pattern) && is_string(key($pattern))) {
1✔
102
                        $patterns = array_map(static fn($p) => $p . 'ux', array_keys($pattern));
1✔
103
                        return self::pcre('preg_replace', [$patterns, array_values($pattern), $subject, $limit]);
1✔
104

105
                } else {
106
                        return self::pcre('preg_replace', [$pattern . 'ux', $replacement, $subject, $limit]);
1✔
107
                }
108
        }
109

110

111
        public static function quote(string $s): string
1✔
112
        {
113
                return addcslashes($s, "\x00..\x20-.\\+*?[^]$(){}=!<>|:-#");
1✔
114
        }
115

116

117
        /** @internal */
118
        public static function pcre(string $func, array $args)
1✔
119
        {
120
                $res = @$func(...$args);
1✔
121
                if (($code = preg_last_error()) // run-time error, but preg_last_error & return code are liars
1✔
122
                        && ($res === null || !in_array($func, ['preg_replace_callback', 'preg_replace'], true))
1✔
123
                ) {
UNCOV
124
                        throw new RegexpException(preg_last_error_msg() . ' (pattern: ' . implode(' or ', (array) $args[0]) . ')', $code);
×
125
                }
126

127
                return $res;
1✔
128
        }
129
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc