Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 代理项对检测失败_.net_Regex_Unicode_F#_Surrogate Pairs - Fatal编程技术网

.net 代理项对检测失败

.net 代理项对检测失败,.net,regex,unicode,f#,surrogate-pairs,.net,Regex,Unicode,F#,Surrogate Pairs,我在F#中做一个小项目,涉及将现有的C#代码移植到F#,我似乎遇到了两种语言之间正则表达式处理方式的差异(我发布这篇文章是希望发现我只是做错了什么) 这个小函数使用正则表达式技巧简单地检测代理项对。以下是当前的实现: let isSurrogatePair input = Regex.IsMatch(input, "[\uD800-\uDBFF][\uDC00-\uDFFF]") 如果我对一个已知的代理项对执行它,如下所示: let result = isSurrogatePair "

我在F#中做一个小项目,涉及将现有的C#代码移植到F#,我似乎遇到了两种语言之间正则表达式处理方式的差异(我发布这篇文章是希望发现我只是做错了什么)

这个小函数使用正则表达式技巧简单地检测代理项对。以下是当前的实现:

let isSurrogatePair input =
    Regex.IsMatch(input, "[\uD800-\uDBFF][\uDC00-\uDFFF]")
如果我对一个已知的代理项对执行它,如下所示:

let result = isSurrogatePair "There appears to be a bug in how F# encodes escaped Unicode characters.
Here's from the F# Interactive (note the last two results):

> "\uD500".[0] |> uint16 ;;
val it : uint16 = 54528us
> "\uD700".[0] |> uint16 ;;
val it : uint16 = 55040us
> "\uD800".[0] |> uint16 ;;
val it : uint16 = 65533us
> "\uD900".[0] |> uint16 ;;
val it : uint16 = 65533us

let result=isSurrogatePair”F#编码转义Unicode字符的方式似乎存在错误。
以下是F#Interactive(注意最后两个结果):

幸运的是,此解决方案可以工作:

let isSurrogatePair input =
  let chrToStr code = new System.String( [| char code |] )
  let regex = "[" + (chrToStr 0xD800) + "-" + (chrToStr 0xDBFF) + "][" + (chrToStr 0xDC00) + "-" + (chrToStr 0xDFFF) + "]"
  Regex.IsMatch(input,  regex)
基于这一发现,我可以构建一个
isSurrogatePair
的修正版(或者说变通版):

Regex.IsMatch(input, "[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]")
// or
Regex.IsMatch(input, @"[\uD800-\uDBFF][\uDC00-\uDFFF]")
此版本正确返回您输入的
true


我刚刚在GitHub上提交了这个问题:

似乎这是一个合法的F#bug,没有任何争议。只是想建议一些替代解决方案


不要将问题字符嵌入字符串本身,请使用正则表达式的常规unicode支持指定它们。匹配unicode代码点
XXXX
的正则表达式模式是
\uxxx
,因此只需转义反斜杠或使用逐字字符串:

// high surrogate followed by low surrogate
Regex.IsMatch(input, @"(\p{IsHighSurrogates}|\p{IsHighPrivateUseSurrogates})\p{IsLowSurrogates}")

对unicode块使用内置正则表达式支持:

// 2 characters, each of which is half of a surrogate pair
// (maybe could give false-positive if both are, e.g. low-surrogates)
Regex.IsMatch(input, @"\p{Cs}{2}")
或财产


对于后代:最新版本的F#解决了这个问题,文字不再显示这种编码问题。
// 2 characters, each of which is half of a surrogate pair
// (maybe could give false-positive if both are, e.g. low-surrogates)
Regex.IsMatch(input, @"\p{Cs}{2}")