@@ -109,11 +109,11 @@ fn is_hex(c: char) -> bool {
109
109
/// If `first` is true, then `c` is treated as the first character in the
110
110
/// group name (which must be alphabetic or underscore).
111
111
fn is_capture_char ( c : char , first : bool ) -> bool {
112
- c == '_'
113
- || ( !first
114
- && ( ( '0' <= c && c <= '9' ) || c == '.' || c == '[' || c == ']' ) )
115
- || ( 'A' <= c && c <= 'Z' )
116
- || ( 'a' <= c && c <= 'z' )
112
+ if first {
113
+ c == '_' || c . is_alphabetic ( )
114
+ } else {
115
+ c == '_' || c == '.' || c == '[' || c == ']' || c . is_alphanumeric ( )
116
+ }
117
117
}
118
118
119
119
/// A builder for a regular expression parser.
@@ -3910,6 +3910,55 @@ bar
3910
3910
} ) )
3911
3911
) ;
3912
3912
3913
+ assert_eq ! (
3914
+ parser( "(?P<a¾>)" ) . parse( ) ,
3915
+ Ok ( Ast :: Group ( ast:: Group {
3916
+ span: Span :: new(
3917
+ Position :: new( 0 , 1 , 1 ) ,
3918
+ Position :: new( 9 , 1 , 9 ) ,
3919
+ ) ,
3920
+ kind: ast:: GroupKind :: CaptureName {
3921
+ starts_with_p: true ,
3922
+ name: ast:: CaptureName {
3923
+ span: Span :: new(
3924
+ Position :: new( 4 , 1 , 5 ) ,
3925
+ Position :: new( 7 , 1 , 7 ) ,
3926
+ ) ,
3927
+ name: s( "a¾" ) ,
3928
+ index: 1 ,
3929
+ }
3930
+ } ,
3931
+ ast: Box :: new( Ast :: Empty ( Span :: new(
3932
+ Position :: new( 8 , 1 , 8 ) ,
3933
+ Position :: new( 8 , 1 , 8 ) ,
3934
+ ) ) ) ,
3935
+ } ) )
3936
+ ) ;
3937
+ assert_eq ! (
3938
+ parser( "(?P<名字>)" ) . parse( ) ,
3939
+ Ok ( Ast :: Group ( ast:: Group {
3940
+ span: Span :: new(
3941
+ Position :: new( 0 , 1 , 1 ) ,
3942
+ Position :: new( 12 , 1 , 9 ) ,
3943
+ ) ,
3944
+ kind: ast:: GroupKind :: CaptureName {
3945
+ starts_with_p: true ,
3946
+ name: ast:: CaptureName {
3947
+ span: Span :: new(
3948
+ Position :: new( 4 , 1 , 5 ) ,
3949
+ Position :: new( 10 , 1 , 7 ) ,
3950
+ ) ,
3951
+ name: s( "名字" ) ,
3952
+ index: 1 ,
3953
+ }
3954
+ } ,
3955
+ ast: Box :: new( Ast :: Empty ( Span :: new(
3956
+ Position :: new( 11 , 1 , 8 ) ,
3957
+ Position :: new( 11 , 1 , 8 ) ,
3958
+ ) ) ) ,
3959
+ } ) )
3960
+ ) ;
3961
+
3913
3962
assert_eq ! (
3914
3963
parser( "(?P<" ) . parse( ) . unwrap_err( ) ,
3915
3964
TestError {
@@ -3968,6 +4017,60 @@ bar
3968
4017
} ,
3969
4018
}
3970
4019
) ;
4020
+ assert_eq ! (
4021
+ parser( "(?P<5>)" ) . parse( ) . unwrap_err( ) ,
4022
+ TestError {
4023
+ span: span( 4 ..5 ) ,
4024
+ kind: ast:: ErrorKind :: GroupNameInvalid ,
4025
+ }
4026
+ ) ;
4027
+ assert_eq ! (
4028
+ parser( "(?P<5a>)" ) . parse( ) . unwrap_err( ) ,
4029
+ TestError {
4030
+ span: span( 4 ..5 ) ,
4031
+ kind: ast:: ErrorKind :: GroupNameInvalid ,
4032
+ }
4033
+ ) ;
4034
+ assert_eq ! (
4035
+ parser( "(?P<¾>)" ) . parse( ) . unwrap_err( ) ,
4036
+ TestError {
4037
+ span: Span :: new(
4038
+ Position :: new( 4 , 1 , 5 ) ,
4039
+ Position :: new( 6 , 1 , 6 ) ,
4040
+ ) ,
4041
+ kind: ast:: ErrorKind :: GroupNameInvalid ,
4042
+ }
4043
+ ) ;
4044
+ assert_eq ! (
4045
+ parser( "(?P<¾a>)" ) . parse( ) . unwrap_err( ) ,
4046
+ TestError {
4047
+ span: Span :: new(
4048
+ Position :: new( 4 , 1 , 5 ) ,
4049
+ Position :: new( 6 , 1 , 6 ) ,
4050
+ ) ,
4051
+ kind: ast:: ErrorKind :: GroupNameInvalid ,
4052
+ }
4053
+ ) ;
4054
+ assert_eq ! (
4055
+ parser( "(?P<☃>)" ) . parse( ) . unwrap_err( ) ,
4056
+ TestError {
4057
+ span: Span :: new(
4058
+ Position :: new( 4 , 1 , 5 ) ,
4059
+ Position :: new( 7 , 1 , 6 ) ,
4060
+ ) ,
4061
+ kind: ast:: ErrorKind :: GroupNameInvalid ,
4062
+ }
4063
+ ) ;
4064
+ assert_eq ! (
4065
+ parser( "(?P<a☃>)" ) . parse( ) . unwrap_err( ) ,
4066
+ TestError {
4067
+ span: Span :: new(
4068
+ Position :: new( 5 , 1 , 6 ) ,
4069
+ Position :: new( 8 , 1 , 7 ) ,
4070
+ ) ,
4071
+ kind: ast:: ErrorKind :: GroupNameInvalid ,
4072
+ }
4073
+ ) ;
3971
4074
}
3972
4075
3973
4076
#[ test]
0 commit comments