【问题标题】:Find the diacritic in the string [closed]在字符串中找到变音符号[关闭]
【发布时间】:2021-12-11 06:30:12
【问题描述】:

我正在做一些搜索,发现了一个类似的主题 Powershell find non-ASCII characters in text file

下面的我的函数不能处理所有情况,例如撇号或所有特殊字符

function IsStringDiacritic {
    param (
        [parameter(Mandatory = $True)][string]$String
    )
    
    If ($String -as [System.Net.Mail.MailAddress]) {
        $String = $String.Split('@')[0]
    }

    Return [bool]($String -cmatch '[^\x20-\x7F]')
}

以上是我制作的功能,但我没有得到我需要的功能。

我想发送函数 first.last,如果有变音符号返回 true 或 false。

我的函数能够处理电子邮件地址以及测试然后拆分,但这不是主要部分。

我想我需要一个可以查看 first.last 或 first last 的正则表达式,但我不确定如何包含这些可能性。

有更好的想法吗?

【问题讨论】:

  • 如果您需要查找变音符号,为什么要使用匹配除可打印 ASCII 以外的任何字符的模式?使用-match '\p{M}'
  • 这里可能有一些东西,但我对你的答案的测试都没有奏效。 @WiktorStribiżew
  • @WiktorStribiżew 指的是 变音符号 的字面定义,它是一个标记,例如 COMBINING DIAERESIS,U+0308),它修饰另一个字符,通常形成一个重音字符,这可能就是您的意思。 \p{M] 匹配这样的标记。但是,鉴于此类标记在 .NET 中很少作为单独的[char] 实例(Unicode 代码单元)使用,因此很少有用(参见下一条评论)。
  • 背景:Unicode有多种等效方式来表示重音字符:作为一个single代码点来表示composed 形式,例如ä(代码点0xe4)或分解形式:'a',后跟上述分音符('a' + [char] 0x308)。两者 render 相同,-eq 识别等价 - 但 -match 不识别。鉴于重音字符的组合的单码点形式远比分解的双码点形式更常见,匹配\p{M] 很少有用,因为它只匹配变音符号,作为一个单独的代码单元
  • 看来我的整个问题都是错误的,我对规则的理解并不完整。我需要的是找到一个电子邮件地址是否有[!#$%^&*(`/?,'' äöüßÄÖÜ)] 在我在这里得到所有帮助之后,我做了以下事情。 function IsStringSpecialCharacters { param ( [parameter(Mandatory = $True)][string]$String ) $String -match '[!#$%^&*(`/?,'' äöüßÄÖÜ)]' } 如果电子邮件地址包含我定义的任何特殊字符,则返回 true。

标签: regex powershell


【解决方案1】:

看起来您的真正意图不是查找带有变音符号的字符,而是确保给定名称 - 无论是单独指定还是作为电子邮件地址的用户名部分(@ 之前的部分) - 组成以下:

  • 小写 ASCII 范围(英文)字母,即 az
  • . 或空格(如果有)用于分隔名称组件。

PowerShell 惯用的解决方案是定义一个Test-Name 函数来指示给定名称是否有效

function Test-Name {

  param (
      [Parameter(Mandatory)]
      [string]$Name
  )
  
  $Name -cmatch '^[a-z]+(?:[. ][a-z]+)?(?:@.+)?$'

}

使用例如foo.barfoo barfoo.bar@example.orgfoobar@example.org调用Test-Name会产生$true,而föo.bärFoo.barfoo-bar和@987654产量$false

注意:

  • 如果大写英文字母也可以接受,请将-cmatch替换为-match

  • 要允许额外的分隔符,请将它们添加到[. ] 字符集中;例如,要包含-_,请使用[. _-](将- 放在首位或末位,这样它就不会被解释为字符范围 的一部分,例如在[a-z])

  • (?:@.+)? 匹配以@ 开头的所有内容(如果存在)(但对@ 后面的内容没有任何限制,除非必须包含至少一个字符)。

  • 注意整个字符串是如何匹配的,以确保名称不以. 或空格开始结束,并且只有一个 存在分隔符。

    • 如果您还想允许,例如,三个名称组件(例如'foo.bar.baz'),请使用以下正则表达式:
      • ^[a-z]+(?:[. ][a-z]+){0,2}(?:@.+)?$

【讨论】:

  • 因为如果不遵守或不理解规则,由于我的许多错误,这是一个封闭的话题。我试图定义我想要什么。看来我的问题应该是如何找到电子邮件字符串是否包含 !#$%^&*(`) 之类的章程 上面的答案有效,但不适合我的需要。
  • @dcaz,即使没有明确定义。究竟是什么定义了不需要的字符?如果您可以轻松枚举它们,请使用字符集 ([...]),例如[!#$%^&*(`)]。但是,最好指定您希望 allow 的那些字符,如本答案所示。如果[a-z] 不够,请添加额外的字符there,例如[a-z0-9],以便也允许十进制数字。同样,为了也允许使用大写字符,请使用 -match 而不是 -cmatch
【解决方案2】:

目前看来可行的答案如下。

function IsStringDiacritic {
    param (
        [parameter(Mandatory = $True)][string]$String
    )
    
    If ($String -as [System.Net.Mail.MailAddress]) {
        $String = $String.Split('@')[0]
    }
    
    If ($String -like '*.*') {
        $String = $String.Replace('.', '')
    }

    $String = $String.Trim()
    
    Return [bool]($String -cmatch '[^a-z]')
}

我的原始功能并未处理所有情况,例如撇号或某人可能错误或故意使用的所有特殊字符。 到目前为止,我的功能似乎告诉我是否有任何不是 a 到 z 的字符。它的限制是英语。

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    相关资源
    最近更新 更多