REBOL Forum Recent REBOL Forum Topics comparing characters in a string with pick Also see: If you study that little FAQ response, you will understand it better. , Posted by: Stone Johnson 20-Sep-2019/13:23:26-7:00 Is flood (from the VID dialect) broken? You are right! The example given does not match the picture., Posted by: Stone Johnson 31-Aug-2019/16:11:51-7:00 Parsing a Python line; why does this even work? From Chapter 15 of the REBOL Core Manual: Parsing splits a sequence of characters or values into smaller parts...parse ... has the general form: parse series rules The series argument is the input [to be] parsed and can be a string or a block. If the argument is a string, it is parsed by character. ... parse ... also accepts two refinements: /all and /case. The /all refinement parses all the characters within a string, including all delimiters, such as space, tab, newline, comma, and semicolon. ... parse ... normally ignores all intervening whitespace between patterns that it scans. To enforce a specific spacing convention, use parse with the /all refinement. ... parse ... splits the input ... string into a block of multiple strings, breaking each string wherever it encounters a delimiter Thus: parse/all ODBC-CONNECTIONS "=^/" Says this: parse all characters in the string splitting only each encountered equal sign and each encountered newline. Try something simplier first: >> parse "Test1=This Test2=That" "=^/" == ["Test1" "This" "Test2" "That"] or the string spanning two lines: >> parse first [ {Test3=this { Test4=that}] "=^/" == ["Test3" "this" "Test4" "that"] Without the /all refinement, parse breaks on the =, the " " and the invisible newline, see: >> newline == #"^/" Now, what happens with the /all refinement? >> parse/all "Test1=This Test2=That" "=^/" == ["Test1" "This Test2" "That"] Because REBOL is now checking every character, including ones not visible to you, i.e., space, REBOL uses parse to break on = which gives: "Test1" and then it passes the space because it has no rule for it and finds the next equal, which it splits on, which gives: "This Test2" And then it finds the newline at the end of the second that, which gives: "That" With a string spanning lines, what happens? >> parse/all first [ {Test3=this { Test4=that}] "=^/" == ["Test3" "this " "Test4" "that"] REBOL using parse breaks on = "Test3" and then on newline "this " and then on = "Test4" and then on newline "that" , Posted by: Stone Johnson 24-Aug-2019/15:20:25-7:00 Referring to next/prev series entries Given: x: [] loop 10 [append x make object! [r: random 100]] From the answers above, this does not work: forall x [print x/1/r - x/-1/r] And yes, Chris caught his error. Proof: >> forall x [print x/1/r - x/-1/r] ** Script Error: Cannot use path on none! value ** Where: forskip ** Near: forall x [print x/1/r - x/-1/r] However, this does: out1: copy [] n: 2 until [ append out1 reduce [x/(n)/r - x/(n - 1)/r] n: n + 1 n = (1 + length? x) ] Proof: out2: copy [] x: head x forskip x 2 [ append out2 reduce [negate x/1/r '+ x/2/r] if not none? ok: attempt [ reduce [negate x/2/r '+ x/3/r]][append out2 ok] ] print out1 print reduce out2 , Posted by: Stone Johnson 23-Aug-2019/18:17:41-7:00 Parsing baby steps hr: head-rules: [ 3 "=" copy hgd some [letter | figure] to newline ( append page maketag 'h1 hgd ) ] pr: para-rules: [ copy pg some letter copy x figure dash copy y figure to newline ( append page maketag 'p rejoin [pg " " x "-" y] ) ] maketag: func [ tag [word!] text [string!] ][ rejoin ["" build-tag reduce [tag] text build-tag to-block rejoin ["/" tag]] ] rules: [ any [() newline | some head-rules | some para-rules] to end ] >> parse md rules == true >> page == {<h1>Heading 1</h1><p>Paragraph 1-1</p><h1>Heading 2</h1><p>Paragraph 2-1</p>} , Posted by: REFACTORING FROM ABOVE 21-Aug-2019/1:58:13-7:00 Explaining parse rules Errata: In 3. 1 or more times consume characters 1 or more times consume delimiters , Posted by: Stone Johnson 21-Aug-2019/0:23:21-7:00 Rebol vs. FizzBuzz Addendum: | is a word of my Red instance, which returns a float! in Red because Red only returns the whole number part of a quotient when dividing and tosses away the fractional part. USAGE: value1 / value2 DESCRIPTION: Returns the quotient of two values. / is an op! value. ARGUMENTS: value1 [number! char! pair! tuple! vector! time!] "The dividend (numerator)." value2 [number! char! pair! tuple! vector! time!] "The divisor (denominator)." RETURNS: [number! char! pair! tuple! vector! time!] REBOL 2.7.8 does not have this problem., Posted by: Stone Johnson 20-Aug-2019/23:46:54-7:00 Parse pattern matching ;; Here is how I do it. ;; First, I write out what needs to be done in p-code. ;; And then I try code at the console ;; For every file, i.e., for all ;; REBOL should try to match those beginning with CV ;; while ignore the rest of the filename crud ;; REBOL should add those that have matched to a block names: copy [] forall filenames [ parse filenames/1 [ "CV" skip to end ( append names filenames/1 ) ] ] ;; non-parse way names: copy [] forall filenames [ if equal? 1 index? find filenames/1 %CV [append names filenames/1] ] Why? Hint: We're asking REBOL to append to a block! only those finds that have a "head view," i.e., have an index position of one See? views: copy [] forall filenames [ if i: index? find filenames/1 %CV [ append views join "view of find starts at: " i ] ] new-line/all views on probe views, Posted by: Stone Johnson 20-Aug-2019/23:23:34-7:00 More parsing confusion Errata for the above: This: you have told REBOL to give you a view of the string! from index position of 3. Should be: This: you have told REBOL to give you a view of the string! from index position of 4. , Posted by: Stone Johnson 20-Aug-2019/17:29:26-7:00 Parse for Pattern Matching exercise Hi Steven. From: "Rich Set of Built-in Datatypes In addition to the datatypes found in most languages, REBOL can also express money, times, dates, words, tags, logic, lists, hashes, tuples, XY pairs, and many other datatypes." Given that, why use string parsing, which is char! by char! when you can leverage REBOL to the fullest and parse on datatypes, in this case, email! ;; the dopey passes data along in strings >> stringemail: "" == "" ;; Here is a fast way, perhaps the fastest way to validate a string email >> email? attempt [to-email "" ] == true ;; REBOL will transmute string emails into email! ;; That is your first hint it is valid. >> to-email stringemail: "" == ;; you can put anything into a block way fast >> to-block to-email stringemail: "" == [] >> parse to-block to-email stringemail: "" [email!] == true ;; or >> parse to-block to-email "" [email!] == true ;; or >> parse reduce [to-email ""] [email!] == true ;; or >> temp: copy [] == [] >> append temp 'to-email == [to-email] >> append temp "" == [to-email ""] >> parse reduce temp [email!] == true But if you truly want to muck around with strings, let's get into it. 1. The word parse labels a function. 2. That function reads string!(s) or block!(s) and attempts to get meaning from the implied patterns matched against specified patterns. 3. Said another way, the input might imply a pattern that you hope matches a pattern you need. The key requirements of Parse. 1. Parsing rules must be written in the Parse dialect. 2. Parsing rules must be in a rules block. 3. Data must be a series! (either a string! or a block!). OK, so let's do a bit of comparison to series! in REBOL. Let's say you have this string. Well, you should know for any string!, which REBOL "models" internally, REBOL has a pointer that tracks where you (or your "script," i.e., messages to REBOL) to be in the string! >> s: "This is a well-meaning sentence." == "This is a well-meaning sentence." >> index? s == 1 ;; you're at the head of s. You have a "head view" of it. >> head? s == true ;; now let's skip "down" (maybe that should be across) the string by 1 >> s: next s == "his is a well-meaning sentence." >> index? s == 2 ;; The first bit of the string did not disappear. REBOL still has the whole string!. >> head s == "This is a well-meaning sentence." ;; Even though the current view of the string starts from index 2. >> s == "his is a well-meaning sentence." ;; More skipping >> s: next s == "is is a well-meaning sentence." >> index? s == 3 ;; this is more like a leap by comparison >> s: skip s 5 == " a well-meaning sentence." >> index? s == 8 OK, why am I focusing your thoughts on this? Well, when you tell REBOL to parse a string. That is why at REBOL does, one character at a time. The difference is this though. For each character where the current index is, REBOL tries to match that character to a rule within your rules block! If a match happens REBOL can skip one and start again with the "next" rule in your rules block! When REBOL applies parse (the function) against input (string! or block!), REBOL checks to see if the left and right hand sides are the same. REBOL will keep applying parse until either a failure or reaching "input exhaustion," that is reaching the end by matching everything. A failure makes REBOL return false and stops the matching (parsing) regardless of how much stuff remains. At input exhaustion, REBOL returns true. Let's break down your problem into two problems: 1. Parse the name. 2. Parse the domain. OK, as I see your problem constraints: 1. No name can start with a dot or end with a dot. 2. Names can begin with underscores, hyphens along with letters and numbers. 3. No domain can start with a hyphen or end with a hyphen, Posted by: Stone Johnson 20-Aug-2019/3:06:20-7:00