如何检查char是否符合charset?

how to check if char conforms to charset?

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 是否符合字符集的东西,但没找到。

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

parse to-string #"." [special]

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

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

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

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

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

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

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

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

是用sentence-case写的吗?你想出的不同语法可以产生相同的结果。

>> 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). The best way to do that is by joining Gitter chat to get promptly help with your questions and code, and by studying community-provided learning resources; Rebol/Core User Guide 是一个很好的起点。

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

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

您需要 copy 因为它改变了原件,strict-equal? 因为普通 equal?不区分大小写

difference显示两组不同的项目。查看帮助差异。 您可以获得与众不同的解决方案

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

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

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