在PARSE方言中,人们如何寻求TO或THRU的CHARSET?

时间:2012-11-19 10:57:31

标签: parsing rebol bitset

首先,我将说明我的意图:我正在尝试为可能混淆的10位数电话号码编写一个解析规则。想象一下像"callmeNOW...555___555____5555!"

这样的案例

我认为开始的地方是维基百科的valid area codes列表。然后我将这些转换为管道分隔的STRING!用作解析规则,我寻求TO

之后我想我会尝试阅读接下来的10位数字。但是我期望工作的概念验证没有:

>> digit: charset "0123456789"
== make bitset! #{000000000000FFC0}

>> parse "callmeNOW...555___555____5555!" [10 [thru digit] to end]
== false

引导我进行一项更简单的测试,但未能达到我想要的效果:

>> parse "5" [thru digit]
== false

如果我不将它与THRU一起使用,那么它可以做到预期的事情:

>> parse "5" [digit]
== true

为什么在用作令牌而不用TOTHRU时支持位集?


P.S。这里是区域代码列表作为Rebol块,如果有人想要它......

valid-area-codes: [
    205 251 256 334 659 938 907 250 480 520 602 623 928 327 479 501 870
    209 213 310 323 341 369 408 415 424 442 510 530 559 562 619 626 627
    628 650 657 661 669 707 714 747 760 764 805 818 831 858 909 916 925
    935 949 951 303 719 720 970 203 475 860 959 302 202 239 305 321 352
    386 407 561 689 727 754 772 786 813 850 863 904 941 954 229 404 470
    478 678 706 762 770 912 808 208 217 224 309 312 331 447 464 618 630
    708 730 773 779 815 847 872 219 260 317 574 765 812 319 515 563 641
    712 316 620 785 913 270 364 502 606 859 225 318 337 504 985 207 227
    240 301 410 443 667 339 351 413 508 617 774 781 857 978 231 248 269
    313 517 586 616 679 734 810 906 947 989 218 320 507 612 651 763 952
    228 601 662 769 314 417 557 573 636 660 816 975 406 308 402 531 702
    775 603 201 551 609 732 848 856 862 908 973 505 575 212 315 347 516
    518 585 607 631 646 716 718 845 914 917 929 252 336 704 828 910 919
    980 984 701 216 234 283 330 380 419 440 513 567 614 740 937 405 539
    580 918 458 503 541 971 215 267 272 412 445 484 570 582 610 717 724
    814 835 878 401 803 843 864 605 423 615 731 865 901 931 210 214 254
    281 325 361 409 430 432 469 512 682 713 737 806 817 830 832 903 915
    936 940 956 972 979 385 435 801 802 276 434 540 571 703 757 804 206
    253 360 425 509 564 304 681 262 274 414 534 608 715 920 307
]

3 个答案:

答案 0 :(得分:1)

当然,虽然R3确实沿着一点移动parse,但通常的模式是创建一个互补的位集来跳过所需的集合。

filler: complement digit: charset "0123456789"
parse/all stream [any [copy n some digit (append out: [] n) | some filler]]
probe out   ; all the digit chunks in the stream

答案 1 :(得分:1)

真正的答案是TO和THRU不是模式匹配运算符,而是搜索运算符。

Charsets专门用于模式匹配,因此它们是一个位掩码,因此您无法搜索它们,它们不存在于流中,它们会过滤掉& amp;比较它,一次一个字节。这并不意味着他们将来不能被用于TO / THRU,这也就是为什么他们到目前为止并不打算这样使用。

您的“管道规则”示例有效的原因(实际上是使用OR(“|”)操作的备选列表)是TO / THRU将按给定顺序搜索每个备选项,直到匹配一个(所以订购应该改变速度,在很长的替代品列表中)。

以下规则将提取所有相对格式良好的电话号码,允许形式(R2& R3)的某些“摆动空间”:

digit: charset "0123456789"
!digit: complement digit

parse/all text [   
    any [ 
        copy phone [ opt "(" 3 digit    1 3 !digit   3 digit    1 3 !digit    4 digit] (print phone)  
        |  skip 
    ] 
]

请注意,以上是适用于任何北美手机的快速且脏的数字提取器。它将扫描整个文本,打印它找到的任何数字。

答案 2 :(得分:0)

不简洁,但如果我不构建我的数字集作为BITSET!但是使用管道规则,它可以正常工作:

>> digit: ["0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"]
== ["0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"]

>> parse "callmeNOW...555___555____5555!" [10 [thru digit] to end]
== true