Skip to content

Commit 858ba20

Browse files
committed
Improve QName+NCName regexps
1 parent 3c969d1 commit 858ba20

4 files changed

Lines changed: 37 additions & 2 deletions

File tree

src/XML/Assert/NCNameTrait.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,21 @@
1111
*/
1212
trait NCNameTrait
1313
{
14-
private static string $ncname_regex = '/^[a-z_][\w.-]*$/Dui';
14+
private static string $ncname_regex = '/
15+
(?(DEFINE)
16+
(?<NCNameStartChar>
17+
[A-Z_a-z\x{C0}-\x{D6}\x{D8}-\x{F6}\x{F8}-\x{2FF}\x{370}-\x{37D}\x{37F}-\x{1FFF}\x{200C}-\x{200D}\x{2070}-\x{218F}\x{2C00}-\x{2FEF}\x{3001}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFFD}\x{10000}-\x{EFFFF}]
18+
)
19+
(?<NCNameChar>
20+
(?&NCNameStartChar)
21+
|[-.0-9\x{B7}\x{0300}-\x{036F}\x{203F}-\x{2040}]
22+
)
23+
(?<NCName>
24+
(?&NCNameStartChar)(?&NCNameChar)*
25+
)
26+
)
27+
^(?&NCName)$
28+
/uxD';
1529

1630

1731
/**

src/XML/Assert/QNameTrait.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,21 @@
1111
*/
1212
trait QNameTrait
1313
{
14-
private static string $qname_regex = '/^([a-z_][\w.-]*)(:[a-z_][\w.-]*)?$/Di';
14+
private static string $qname_regex = '/
15+
(?(DEFINE)
16+
(?<NCNameStartChar>
17+
[A-Z_a-z\x{C0}-\x{D6}\x{D8}-\x{F6}\x{F8}-\x{2FF}\x{370}-\x{37D}\x{37F}-\x{1FFF}\x{200C}-\x{200D}\x{2070}-\x{218F}\x{2C00}-\x{2FEF}\x{3001}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFFD}\x{10000}-\x{EFFFF}]
18+
)
19+
(?<NCNameChar>
20+
(?&NCNameStartChar)
21+
|[-.0-9\x{B7}\x{0300}-\x{036F}\x{203F}-\x{2040}]
22+
)
23+
(?<NCName>
24+
(?&NCNameStartChar)(?&NCNameChar)*
25+
)
26+
)
27+
^(?:(?<prefix>(?&NCName)):)?(?<local>(?&NCName))$
28+
/uxD';
1529

1630

1731
/**

tests/XML/Assert/NCNameTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public static function provideValidNCName(): array
4646
'valid contains dashes' => [true, '_1950-10-04_10-00'],
4747
'valid contains dots' => [true, 'Te.st'],
4848
'valid contains diacriticals' => [true, 'fööbár'],
49+
'valid contains ideographs' => [true, '東京'],
4950
'valid prefixed v4 UUID' => [true, '_5425e58e-e799-4884-92cc-ca64ecede32f'],
5051
];
5152
}

tests/XML/Assert/QNameTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ public static function provideValidQName(): array
4646
'1st part containing dash' => [true, 'som-e:Test'],
4747
'2nd part containing dash' => [true, 'some:T-est'],
4848
'both parts containing dash' => [true, 'so-me:T-est'],
49+
'single character unprefixed' => [true, 'a'],
4950
// A single NCName is also a valid QName
5051
'no colon' => [true, 'Test'],
52+
'unicode' => [true, 'café:élément'],
53+
'ideographs' => [true, '東京:品'],
5154
];
5255
}
5356

@@ -61,8 +64,11 @@ public static function provideInvalidQName(): array
6164
'start 2nd part with dash' => [false, 'some:-Test'],
6265
'start both parts with dash' => [false, '-some:-Test'],
6366
'start with colon' => [false, ':test'],
67+
'end with colon' => [false, 'test:'],
68+
'empty string' => [false, ''],
6469
'multiple colons' => [false, 'test:test:test'],
6570
'start with digit' => [false, '1Test'],
71+
'colon' => [false, ':'],
6672
'wildcard' => [false, 'Te*st'],
6773
// Trailing newlines are forbidden
6874
'trailing newline' => [false, "some:Test\n"],

0 commit comments

Comments
 (0)