fbtxt-lexer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/Manifest.txt +47 -0
- data/README.md +18 -0
- data/Rakefile +30 -0
- data/lib/fbtxt/lexer/debuggable.rb +58 -0
- data/lib/fbtxt/lexer/lexer-logger.rb +20 -0
- data/lib/fbtxt/lexer/lexer-on_goal.rb +167 -0
- data/lib/fbtxt/lexer/lexer-on_group_def.rb +31 -0
- data/lib/fbtxt/lexer/lexer-on_prop_cards.rb +61 -0
- data/lib/fbtxt/lexer/lexer-on_prop_lineup.rb +82 -0
- data/lib/fbtxt/lexer/lexer-on_prop_misc.rb +108 -0
- data/lib/fbtxt/lexer/lexer-on_prop_penalties.rb +44 -0
- data/lib/fbtxt/lexer/lexer-on_round_def.rb +37 -0
- data/lib/fbtxt/lexer/lexer-on_top.rb +133 -0
- data/lib/fbtxt/lexer/lexer-prep_doc.rb +131 -0
- data/lib/fbtxt/lexer/lexer-prep_line.rb +63 -0
- data/lib/fbtxt/lexer/lexer-props.rb +66 -0
- data/lib/fbtxt/lexer/lexer-tokenize_line.rb +381 -0
- data/lib/fbtxt/lexer/lexer-tokenize_norm.rb +93 -0
- data/lib/fbtxt/lexer/lexer.rb +192 -0
- data/lib/fbtxt/lexer/lexer_buffer.rb +68 -0
- data/lib/fbtxt/lexer/lexer_context.rb +70 -0
- data/lib/fbtxt/lexer/lexer_token.rb +127 -0
- data/lib/fbtxt/lexer/token-date--helpers.rb +130 -0
- data/lib/fbtxt/lexer/token-date--names.rb +108 -0
- data/lib/fbtxt/lexer/token-date.rb +200 -0
- data/lib/fbtxt/lexer/token-date_duration.rb +171 -0
- data/lib/fbtxt/lexer/token-geo.rb +173 -0
- data/lib/fbtxt/lexer/token-goals--helpers.rb +114 -0
- data/lib/fbtxt/lexer/token-goals.rb +306 -0
- data/lib/fbtxt/lexer/token-group.rb +29 -0
- data/lib/fbtxt/lexer/token-note.rb +40 -0
- data/lib/fbtxt/lexer/token-prop.rb +334 -0
- data/lib/fbtxt/lexer/token-prop_name.rb +83 -0
- data/lib/fbtxt/lexer/token-round.rb +88 -0
- data/lib/fbtxt/lexer/token-score--helpers.rb +189 -0
- data/lib/fbtxt/lexer/token-score.rb +60 -0
- data/lib/fbtxt/lexer/token-score_full.rb +331 -0
- data/lib/fbtxt/lexer/token-score_fuller.rb +434 -0
- data/lib/fbtxt/lexer/token-score_legs.rb +59 -0
- data/lib/fbtxt/lexer/token-status.rb +192 -0
- data/lib/fbtxt/lexer/token-status_inline.rb +112 -0
- data/lib/fbtxt/lexer/token-text.rb +221 -0
- data/lib/fbtxt/lexer/token-time.rb +144 -0
- data/lib/fbtxt/lexer/token.rb +224 -0
- data/lib/fbtxt/lexer/version.rb +24 -0
- data/lib/fbtxt/lexer.rb +118 -0
- metadata +142 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module Fbtxt
|
|
2
|
+
class Lexer
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
## see token-text for TEXT_RE
|
|
7
|
+
## change PROP_NAME_RE to TEXT_II or TEXT_??? - why? why not?
|
|
8
|
+
### no do NO change
|
|
9
|
+
## change TEXT_RE to TEAM_RE or TEAM_NAME_RE !!!!
|
|
10
|
+
## it is NOT generic TEXT regex!!!
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
PROP_NAME_WORD_ = %r{
|
|
16
|
+
\p{L}+
|
|
17
|
+
\.? ## optional dot
|
|
18
|
+
}ix
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## todo/fix - remove support for double quotes e.g. "Rodri" - why? why not?
|
|
22
|
+
##
|
|
23
|
+
|
|
24
|
+
## name different from text (**does NOT allow number in name/text**)
|
|
25
|
+
## different from PROP_KEY too
|
|
26
|
+
PROP_NAME_RE = %r{
|
|
27
|
+
(?<prop_name>
|
|
28
|
+
\b
|
|
29
|
+
(?<name>
|
|
30
|
+
#{PROP_NAME_WORD_}
|
|
31
|
+
|
|
32
|
+
## connectors
|
|
33
|
+
(?:
|
|
34
|
+
## (i) space - only one single space allowed inline!!!
|
|
35
|
+
(?:
|
|
36
|
+
### check if negative lookbehind is redudant!!
|
|
37
|
+
## next char is \p{L} and NOT space
|
|
38
|
+
## thus double space not possible!!
|
|
39
|
+
(?<! [ ]) ## use negative lookbehind
|
|
40
|
+
[ ]
|
|
41
|
+
(?= \p{L}|['"]\p{L}) ## use lookahead
|
|
42
|
+
)
|
|
43
|
+
## (ii) support (inline) quoted name e.g. "Rodri" or such
|
|
44
|
+
| (?:
|
|
45
|
+
(?<=[ ]) ## use positive lookbehind
|
|
46
|
+
" \p{L}+ "
|
|
47
|
+
## require space here too - why? why not?
|
|
48
|
+
)
|
|
49
|
+
## (iii) dash (-)
|
|
50
|
+
| (?:
|
|
51
|
+
## use POSITIVE lookBEHIND
|
|
52
|
+
## note - allow leading dot (.) e.g. K.-H.Förster
|
|
53
|
+
## short for Karl-Heinz Förster
|
|
54
|
+
##
|
|
55
|
+
## change to negative lookBEHIND [ '"-]
|
|
56
|
+
## \p{L}\. | \p{L} - not MUST be fixed size
|
|
57
|
+
(?<=
|
|
58
|
+
[\p{L}.]
|
|
59
|
+
)
|
|
60
|
+
[-] ## must be surrounded by letters
|
|
61
|
+
## e.g. One-Two NOT
|
|
62
|
+
## One- Two or One - Two or One -Two etc.
|
|
63
|
+
(?= \p{L}) ## use lookahead
|
|
64
|
+
)
|
|
65
|
+
|
|
|
66
|
+
(?: ## flex rule for quote - allow any
|
|
67
|
+
## only check for double quotes e.g. cannot follow other ' for now - why? why not?
|
|
68
|
+
## allows rodrigez 'rodri' for example
|
|
69
|
+
(?<!') ## use negative lookbehind
|
|
70
|
+
'
|
|
71
|
+
)
|
|
72
|
+
| ## standard case with letter(s) and optional dot
|
|
73
|
+
#{PROP_NAME_WORD_}
|
|
74
|
+
)*
|
|
75
|
+
)
|
|
76
|
+
## add lookahead - must be non-alphanum
|
|
77
|
+
## add colon (:) too - why? why not?
|
|
78
|
+
(?= [ ,;\]\)]|$)
|
|
79
|
+
)}ix
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
end # class Lexer
|
|
83
|
+
end # module Fbtxt
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module Fbtxt
|
|
2
|
+
class Lexer
|
|
3
|
+
|
|
4
|
+
####
|
|
5
|
+
#
|
|
6
|
+
## note - use \A (instead of ^) - \A strictly matches the start of the string.
|
|
7
|
+
##
|
|
8
|
+
## todo - add support for trailing markers e.g.
|
|
9
|
+
## ▪ Round 1 ▪▪▪▪▪▪▪▪
|
|
10
|
+
## :: Round 1 ::::::::::::
|
|
11
|
+
##
|
|
12
|
+
## check - allow without space (like in heading =Heading 1=) - why? why not?
|
|
13
|
+
## ▪Round 1▪▪▪▪▪▪▪▪
|
|
14
|
+
## ::Round 1::::::::::::
|
|
15
|
+
|
|
16
|
+
ROUND_OUTLINE_I_RE = %r{ \A
|
|
17
|
+
[ ]* ## ignore leading spaces (if any)
|
|
18
|
+
(?<round_marker>
|
|
19
|
+
[▪]{1,3} ## BLACK SMALL SQUARE e.g. ▪,▪▪,▪▪▪
|
|
20
|
+
)
|
|
21
|
+
[ ]+
|
|
22
|
+
(?<round_outline>
|
|
23
|
+
## must start with letter - why? why not?
|
|
24
|
+
### 1st round
|
|
25
|
+
## allow numbers e.g. Group A - 1
|
|
26
|
+
##
|
|
27
|
+
## note - CANNOT incl. :| !!!
|
|
28
|
+
## used for markers for defs/definitions
|
|
29
|
+
[^:|]+? ## use non-greedy
|
|
30
|
+
)
|
|
31
|
+
(?:
|
|
32
|
+
[ ]+
|
|
33
|
+
[▪]+
|
|
34
|
+
)?
|
|
35
|
+
[ ]* ## ignore trailing spaces (if any)
|
|
36
|
+
\z
|
|
37
|
+
}xi
|
|
38
|
+
|
|
39
|
+
ROUND_OUTLINE_II_RE = %r{ \A
|
|
40
|
+
[ ]* ## ignore leading spaces (if any)
|
|
41
|
+
(?<round_marker>
|
|
42
|
+
::{1,3} ## e.g. ::,:::,::::
|
|
43
|
+
)
|
|
44
|
+
[ ]+
|
|
45
|
+
(?<round_outline>
|
|
46
|
+
## must start with letter - why? why not?
|
|
47
|
+
### 1st round
|
|
48
|
+
## allow numbers e.g. Group A - 1
|
|
49
|
+
##
|
|
50
|
+
## note - CANNOT incl. :| !!!
|
|
51
|
+
## used for markers for defs/definitions
|
|
52
|
+
[^:|]+? ## use non-greedy
|
|
53
|
+
)
|
|
54
|
+
(?:
|
|
55
|
+
[ ]+
|
|
56
|
+
::+
|
|
57
|
+
)?
|
|
58
|
+
[ ]* ## ignore trailing spaces (if any)
|
|
59
|
+
\z
|
|
60
|
+
}xi
|
|
61
|
+
|
|
62
|
+
ROUND_OUTLINE_RE = Regexp.union( ROUND_OUTLINE_I_RE,
|
|
63
|
+
ROUND_OUTLINE_II_RE,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
###
|
|
68
|
+
# note - for def(initions) only one level support
|
|
69
|
+
# that is, no round outline additions possible (e.g ▪▪ 1st leg etc.)
|
|
70
|
+
ROUND_DEF_OUTLINE_RE = %r{ \A
|
|
71
|
+
[ ]* ## ignore leading spaces (if any)
|
|
72
|
+
(?: [▪] ## BLACK SMALL SQUARE
|
|
73
|
+
|
|
|
74
|
+
:: )
|
|
75
|
+
[ ]+
|
|
76
|
+
(?<round_outline>
|
|
77
|
+
[^:|]+? ## use non-greedy
|
|
78
|
+
)
|
|
79
|
+
[ ]* ## ignore trailing spaces (if any)
|
|
80
|
+
### possitive lookahead MUST be : OR |
|
|
81
|
+
(?= [:|]
|
|
82
|
+
[ ]) ## note: requires space for now after [:|] - keep - why? why not?
|
|
83
|
+
}ix
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
end # class Lexer
|
|
88
|
+
end # module Fbtxt
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
module Fbtxt
|
|
2
|
+
class Lexer
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def self._build_score( m )
|
|
6
|
+
## note - score is "generic"
|
|
7
|
+
## might be full-time (ft) or
|
|
8
|
+
## after extra-time (aet) or such
|
|
9
|
+
## or even undecided/unknown
|
|
10
|
+
## thus, use score1/score2 and NOT ft1/ft2
|
|
11
|
+
## thus, use (simply an) array e.g. [1,2]
|
|
12
|
+
## and NOT hash (table) e.g. { ft: [1,2] } !!!
|
|
13
|
+
|
|
14
|
+
score = [m[:score1].to_i(10),
|
|
15
|
+
m[:score2].to_i(10)]
|
|
16
|
+
|
|
17
|
+
score
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self._build_score_awd( m ) # score awarded (awd/awd.)
|
|
21
|
+
### note - use "generic" score for now
|
|
22
|
+
## to match A 3-0 B [awarded] etc.
|
|
23
|
+
score = [m[:score1].to_i(10),
|
|
24
|
+
m[:score2].to_i(10)]
|
|
25
|
+
## add score[:awarded] = true ???
|
|
26
|
+
## note - for now uses its own token e.g SCORE_AWD
|
|
27
|
+
score
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self._build_score_abd( m ) # score abandonded (abd/abd.)
|
|
31
|
+
### note - use "generic" score for now
|
|
32
|
+
score = [m[:score1].to_i(10),
|
|
33
|
+
m[:score2].to_i(10)]
|
|
34
|
+
## add score[:abd] = true ???
|
|
35
|
+
## note - for now uses its own token e.g SCORE_ABD
|
|
36
|
+
score
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def self._build_score_full( m )
|
|
41
|
+
score = {}
|
|
42
|
+
score[:p] = [m[:p1].to_i(10),
|
|
43
|
+
m[:p2].to_i(10)] if m[:p1] && m[:p2]
|
|
44
|
+
score[:et] = [m[:et1].to_i(10),
|
|
45
|
+
m[:et2].to_i(10)] if m[:et1] && m[:et2]
|
|
46
|
+
score[:ft] = [m[:ft1].to_i(10),
|
|
47
|
+
m[:ft2].to_i(10)] if m[:ft1] && m[:ft2]
|
|
48
|
+
score[:ht] = [m[:ht1].to_i(10),
|
|
49
|
+
m[:ht2].to_i(10)] if m[:ht1] && m[:ht2]
|
|
50
|
+
|
|
51
|
+
## add golden/silver flags
|
|
52
|
+
score[:golden] = true if m[:aetgg] ## golden goal (gg)/sudden death (sd)
|
|
53
|
+
score[:silver] = true if m[:aetsg] ## silver goal (sg)
|
|
54
|
+
|
|
55
|
+
score
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self._build_score_fuller( m )
|
|
59
|
+
score = {}
|
|
60
|
+
score[:p] = [m[:p1].to_i(10),
|
|
61
|
+
m[:p2].to_i(10)] if m[:p1] && m[:p2]
|
|
62
|
+
score[:et] = [m[:et1].to_i(10),
|
|
63
|
+
m[:et2].to_i(10)] if m[:et1] && m[:et2]
|
|
64
|
+
score[:ft] = [m[:ft1].to_i(10),
|
|
65
|
+
m[:ft2].to_i(10)] if m[:ft1] && m[:ft2]
|
|
66
|
+
score[:ht] = [m[:ht1].to_i(10),
|
|
67
|
+
m[:ht2].to_i(10)] if m[:ht1] && m[:ht2]
|
|
68
|
+
score[:agg] = [m[:agg1].to_i(10),
|
|
69
|
+
m[:agg2].to_i(10)] if m[:agg1] && m[:agg2]
|
|
70
|
+
|
|
71
|
+
if m[:away1] && m[:away2]
|
|
72
|
+
score[:away] = [m[:away1].to_i(10),
|
|
73
|
+
m[:away2].to_i(10)]
|
|
74
|
+
elsif m[:away] ## fallback if no away score; check away flag
|
|
75
|
+
score[:away] = true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
## add golden/silver flags
|
|
79
|
+
score[:golden] = true if m[:aetgg] ## golden goal (gg)/sudden death (sd)
|
|
80
|
+
score[:silver] = true if m[:aetsg] ## silver goal (sg)
|
|
81
|
+
|
|
82
|
+
score
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def self._build_score_fuller_more( m )
|
|
87
|
+
## SCORE + SCORE_FULLER_MORE
|
|
88
|
+
## note - after extra-time (aet) or full-time (ft)
|
|
89
|
+
## score may be present in SCORE!!!
|
|
90
|
+
score = {}
|
|
91
|
+
score[:p] = [m[:p1].to_i(10),
|
|
92
|
+
m[:p2].to_i(10)] if m[:p1] && m[:p2]
|
|
93
|
+
score[:et] = [m[:et1].to_i(10),
|
|
94
|
+
m[:et2].to_i(10)] if m[:et1] && m[:et2]
|
|
95
|
+
score[:ft] = [m[:ft1].to_i(10),
|
|
96
|
+
m[:ft2].to_i(10)] if m[:ft1] && m[:ft2]
|
|
97
|
+
score[:ht] = [m[:ht1].to_i(10),
|
|
98
|
+
m[:ht2].to_i(10)] if m[:ht1] && m[:ht2]
|
|
99
|
+
score[:agg] = [m[:agg1].to_i(10),
|
|
100
|
+
m[:agg2].to_i(10)] if m[:agg1] && m[:agg2]
|
|
101
|
+
|
|
102
|
+
if m[:away1] && m[:away2]
|
|
103
|
+
score[:away] = [m[:away1].to_i(10),
|
|
104
|
+
m[:away2].to_i(10)]
|
|
105
|
+
elsif m[:away] ## fallback if no away score; check away flag
|
|
106
|
+
score[:away] = true
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
## add golden/silver flags
|
|
110
|
+
score[:golden] = true if m[:aetgg] ## golden goal (gg)/sudden death (sd)
|
|
111
|
+
score[:silver] = true if m[:aetsg] ## silver goal (sg)
|
|
112
|
+
|
|
113
|
+
## add flag in score for et/ft/ht
|
|
114
|
+
## used for "dangling" (generic) score
|
|
115
|
+
score[:score] = 'et' if m[:aet] || m[:aetgg] || m[:aetsg]
|
|
116
|
+
score[:score] = 'ft' if m[:ft]
|
|
117
|
+
score[:score] = 'ht' if m[:ht]
|
|
118
|
+
|
|
119
|
+
score
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def self._build_score_legs( m )
|
|
124
|
+
legs = {}
|
|
125
|
+
|
|
126
|
+
############
|
|
127
|
+
### build leg1 (score)
|
|
128
|
+
score = {}
|
|
129
|
+
score[:ft] = [m[:leg1_ft1].to_i(10),
|
|
130
|
+
m[:leg1_ft2].to_i(10)]
|
|
131
|
+
legs['leg1'] = score
|
|
132
|
+
|
|
133
|
+
##################
|
|
134
|
+
### build leg2 (score)
|
|
135
|
+
score = {}
|
|
136
|
+
score[:ft] = [m[:leg2_ft1].to_i(10),
|
|
137
|
+
m[:leg2_ft2].to_i(10)] if m[:leg2_ft1] && m[:leg2_ft2]
|
|
138
|
+
score[:et] = [m[:leg2_et1].to_i(10),
|
|
139
|
+
m[:leg2_et2].to_i(10)] if m[:leg2_et1] && m[:leg2_et2]
|
|
140
|
+
score[:p] = [m[:leg2_p1].to_i(10),
|
|
141
|
+
m[:leg2_p2].to_i(10)] if m[:leg2_p1] && m[:leg2_p2]
|
|
142
|
+
legs['leg2'] = score
|
|
143
|
+
|
|
144
|
+
## check for (opt) aggregate - keep on "top-level"
|
|
145
|
+
legs[:agg] = [m[:agg1].to_i(10),
|
|
146
|
+
m[:agg2].to_i(10)] if m[:agg1] && m[:agg2]
|
|
147
|
+
legs[:away] = true if m[:away]
|
|
148
|
+
|
|
149
|
+
legs
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _build_score( m ) self.class._build_score( m ); end
|
|
154
|
+
def _build_score_awd( m ) self.class._build_score_awd( m ); end
|
|
155
|
+
def _build_score_abd( m ) self.class._build_score_abd( m ); end
|
|
156
|
+
def _build_score_full( m ) self.class._build_score_full( m ); end
|
|
157
|
+
def _build_score_fuller( m ) self.class._build_score_fuller( m ); end
|
|
158
|
+
def _build_score_fuller_more( m ) self.class._build_score_fuller_more( m ); end
|
|
159
|
+
def _build_score_legs( m ) self.class._build_score_legs( m ); end
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
###
|
|
165
|
+
## add parser helpers
|
|
166
|
+
|
|
167
|
+
def self._parse_score_full( str )
|
|
168
|
+
## note - strip - leading/trailing spaces automatic - why? why not?
|
|
169
|
+
|
|
170
|
+
m = Regexp.union(
|
|
171
|
+
SCORE_FULL_1ST_RE,
|
|
172
|
+
SCORE_FULL_RE ).match( str.strip )
|
|
173
|
+
|
|
174
|
+
if m && m.pre_match == '' && m.post_match == ''
|
|
175
|
+
pp m
|
|
176
|
+
_build_score_full( m )
|
|
177
|
+
elsif m
|
|
178
|
+
## note - match BUT not anchored to start and end-of-string!!!
|
|
179
|
+
## report, error somehow??
|
|
180
|
+
nil
|
|
181
|
+
else
|
|
182
|
+
nil ## no match - return nil
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
end # class Lexer
|
|
189
|
+
end # module Fbtxt
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Fbtxt
|
|
2
|
+
class Lexer
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
###
|
|
6
|
+
##
|
|
7
|
+
## add support for score awarded (inline style)
|
|
8
|
+
## 3-0 awd 3-0 awd. 3-0awd
|
|
9
|
+
## 0-1 awd or 0-1 AWD etc.
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
## note - keep AWD w/o dot - why? why not?
|
|
13
|
+
|
|
14
|
+
SCORE_AWD_RE = %r{
|
|
15
|
+
(?<score_awd>
|
|
16
|
+
\b
|
|
17
|
+
(?<score1>\d{1,2}) - (?<score2>\d{1,2})
|
|
18
|
+
[ ]?
|
|
19
|
+
(?-i: awd\.? | AWD )
|
|
20
|
+
## POSITIVE lookahead - requires space
|
|
21
|
+
(?= [ ])
|
|
22
|
+
)}ix
|
|
23
|
+
|
|
24
|
+
###
|
|
25
|
+
##
|
|
26
|
+
## add support for score abandoned (inline style)
|
|
27
|
+
## 2-1 abd. or 2-1 ABD
|
|
28
|
+
SCORE_ABD_RE = %r{
|
|
29
|
+
(?<score_abd>
|
|
30
|
+
\b
|
|
31
|
+
(?<score1>\d{1,2}) - (?<score2>\d{1,2})
|
|
32
|
+
[ ]?
|
|
33
|
+
(?-i: abd\.? | ABD )
|
|
34
|
+
## POSITIVE lookahead - requires space
|
|
35
|
+
(?= [ ])
|
|
36
|
+
)}ix
|
|
37
|
+
|
|
38
|
+
#####
|
|
39
|
+
## 2-1
|
|
40
|
+
###
|
|
41
|
+
### note - was SCORE__FT__RE
|
|
42
|
+
### changed to "generic" SCORE_RE
|
|
43
|
+
### and
|
|
44
|
+
## (?<ft1>\d{1,2}) - (?<ft2>\d{1,2})
|
|
45
|
+
## changed
|
|
46
|
+
## (?<score1>\d{1,2}) - (?<score2>\d{1,2})
|
|
47
|
+
## to
|
|
48
|
+
## pattern match not necessarily the full-time (ft) scoreline!!!
|
|
49
|
+
## - pattern also used for goal seq(uence) e.g. 1-0 Kane, 1-1 Johnson
|
|
50
|
+
SCORE_RE = %r{
|
|
51
|
+
(?<score>
|
|
52
|
+
\b
|
|
53
|
+
(?<score1>\d{1,2}) - (?<score2>\d{1,2})
|
|
54
|
+
\b
|
|
55
|
+
)}ix
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
end # class Lexer
|
|
60
|
+
end # module Fbtxt
|