【问题标题】:Match high ASCII characters (but not the letter i)匹配高位 ASCII 字符(但不匹配字母 i)
【发布时间】:2015-06-12 14:36:46
【问题描述】:

我正在尝试使用 powershell 匹配所有高位 ASCII 和特殊 utf-8 字符:

gc $file -readcount 0 | select-string -allmatches -pattern "[\x80-\uffff]"

它应该找到我想要的所有字符。但是,正则表达式似乎失败了,因为它匹配字符 "i""I"

我跑了这个来测试,我很困惑:

"abcdefghijklmnopqrstuvwxyz" | select-string -allmatches -pattern "[\x80-\uffff]"

为什么匹配"i"?我也没有得到的是,如果将字符转换为 int,则值为 105,这显然不在指定的范围内。

【问题讨论】:

    标签: regex powershell utf-8 ascii


    【解决方案1】:

    原因是i 匹配到U+0130İ, "Latin Capital Letter I with dot above"), a variant of capital I found in Turkish:

    PS C:\> 'i' -match '[\u0130]'
    True
    

    尝试倒置模式:

    "abcdefghijklmnopqrstuvwxyz" | Select-String -AllMatches -Pattern "[^\x00-\x79]"
    

    我是这样发现的:

    0x80..0xffff |ForEach-Object {
        $CharCode = $_.ToString("X4")
        if('i' -match "[\u$CharCode]"){
            "U+$CharCode matches"
        }
    }
    

    【讨论】:

    • [char]0x49 -match '\u0130' 也是 True。这里似乎真的有些不对劲。 i 也匹配 \P{IsBasicLatin},它应该是“不在 0-127 中”。一种解决方法是使用 -cmatch。
    • @js2010 [char]0x49 -match '\u0130' 是正确的 - [char]::ToLower([char]0x130)i ([char]0x49) :) 与 \P{IsBasicLatin} 的比赛对我来说似乎也有问题
    【解决方案2】:

    区分大小写是这个奇怪的土耳其语İ 错误的另一种解决方法。顶部有一个小点。

    "abcdefghijklmnopqrstuvwxyz" | 
      select-string -allmatches -pattern "[\x80-\uffff]" -casesensitive
    

    或者这个,但是字母i(小写或大写)会在不区分大小写的情况下通过:

    # not 0-127
    "abcdefghijklmnopqrstuvwxyz" | 
      select-string -allmatches -pattern "\P{IsBasicLatin}" -casesensitive
    

    那个外来字符的小写字母被认为是英文小写字母i。但它并没有以另一种方式映射(在我们的文化中)。

    'İ'.tolower()     
    i
    
    'i'.toupper()
    I
    

    Kelvin 似乎也有问题。它的小写字母是一个普通的小“k”。当忽略大小写时,它被视为 ascii。我不确定为什么它的行为与土耳其语 İ 不同。

    [char]0x212a | select-string '\P{IsBasicLatin}' # no output
    

    【讨论】:

      猜你喜欢
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多