【问题标题】:how to check if char conforms to charset?如何检查char是否符合charset?
【发布时间】:2020-10-27 10:49:18
【问题描述】:

tl;dr 无法解析以使用单个字母

我目前正在学习 Red,所以我可能缺少基本的东西,但总的来说我想检查密码是否包含大写字符;这是我的第一次尝试(我知道这在逻辑上是无效的):

num-uppercase: (length? (difference/case password (lowercase password))) / 2

想法是转换为小写字符串,然后比较每个,但difference 似乎将字符串转换为集合(?)。

现在我开始循环遍历每个字母,如下所示:

is-uppercase: false
foreach letter password [
    if letter <> lowercase letter [
        is-uppercase: true
        break
    ]
]

但后来我想检查单个 char! letter 是否是特殊字符:

foreach letter password [
    if parse letter special [
        is-special: true
    ]
]

但我得到一个错误:

*** Script Error: parse does not allow char! for its input argument
*** Where: parse
*** Stack:  

我一直在寻找能够检查 char 是否符合 charset 的东西,但没能做到。

【问题讨论】:

    标签: rebol red


    【解决方案1】:

    Parse 几乎适用于任何类型的系列:即连续放置的项目集合。 string!是这样一个系列,但char!不是。

    >> series? #"."
    == false
    >> scalar? #"."
    == true
    

    要检查您的密码是否包含大写字符,您首先需要创建一个代表此类字符的bitset!

    >> upper: charset [#"A" - #"Z"]
    == make bitset! #{00000000000000007FFFFFE0}
    

    之后,你可以用它来构造一个Parse 规则并检查输入的一致性;例如,密码是否全部大写?有些输入会匹配,有些则不会。

    >> parse "YES" [some upper]
    == true
    >> parse "no" [some upper]
    == false
    

    它是用句子大小写的吗?你想出的不同语法可以产生相同的结果。

    >> parse "Sentence" [upper to end]
    == true
    >> parse "Sentence" [upper any [not upper skip]]
    == true
    

    最后,如果你想检查是否至少有一个大写字母,应该这样做:

    >> parse "aBc" [to upper to end]
    == true
    >> parse "abc" [to upper to end]
    == false
    

    如果您正在寻找只有一个大写字母且没有更多的密码,那么:

    >> parse "aBc" [thru upper any [not upper skip]]
    == true
    >> parse "aBC" [thru upper any [not upper skip]]
    == false
    

    直接回答原问题:如果你有一个charset!和一个char!,那么你可以检查后者是否属于前者:

    >> pick upper #"a"
    == false
    >> pick upper #"A"
    == true
    >> pick upper [#"A" #"b"]
    == false
    >> pick upper [#"A" #"B"]
    == true
    >> pick upper "Ab"
    == false
    >> pick upper "AB"
    == true
    

    我强烈建议在处理 Parse 之前先了解 Red 的方位(仅供参考,官方有 documentation)。最好的方法是加入Gitter chat 以及时获得有关您的问题和代码的帮助,并学习社区提供的learning resourcesRebol/Core User Guide 是一个很好的起点。

    【讨论】:

    • pick 非常好,虽然为了检查 somehting 是否为大写,我仍然更喜欢使用 uppercase 函数,以防字符串有变音符号和其他非标准字符。谢谢!
    【解决方案2】:

    Red 中的另一个解决方案是将char! 转换为integer! 并使用path notation

    >> special: charset ".:?"
    == make bitset! #{0000000000020021}
    >> special/(to integer! #"a")
    == false
    >> special/(to integer! #".")
    == true
    

    【讨论】:

    • 这看起来不太地道。 pick special character 做同样的事情,不需要任何转换。
    • 此外,在这种情况下不需要转换为integer!,请尝试例如special/(#".").
    【解决方案3】:

    我可以使用to-string 将字符转换为字符串。这是一种方法。

    parse to-string #"." [special]
    

    【讨论】:

      【解决方案4】:

      不解析,但根据你第一次尝试得到的结果

      >> strict-equal? lowercase copy pass: "ABcc"  pass
      == false
      >> strict-equal? lowercase copy pass: "abcc"  pass
      == true
      

      你需要 copy 因为它改变了原来的,strict-equal? 因为普通的 equal? 不区分大小写。

      差异表示两组的不同项目。请参阅帮助差异。 您可以获得不同的解决方案

      >> same: empty? difference/case pass: "ABcc" lowercase copy pass
      == false
      >> same:  empty? difference/case pass: "aabc" lowercase copy pass
      == true
      

      【讨论】:

        【解决方案5】:

        对于单个字符,find 也可以与字符集一起使用。

        >> upper: charset [#"A" - #"Z"]
        == make bitset! #{00000000000000007FFFFFE0}
        >> find upper #"x"
        == none
        >> find upper #"X"
        == true
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-08-30
          • 1970-01-01
          • 1970-01-01
          • 2011-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多