sportdb-parser 0.7.1 → 0.8.0
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 +4 -4
- data/CHANGELOG.md +1 -1
- data/Manifest.txt +25 -7
- data/Rakefile +23 -0
- data/lib/sportdb/parser/debuggable.rb +53 -0
- data/lib/sportdb/parser/lexer-logger.rb +20 -0
- data/lib/sportdb/parser/lexer-on_goal.rb +167 -0
- data/lib/sportdb/parser/lexer-on_group_def.rb +31 -0
- data/lib/sportdb/parser/lexer-on_prop_lineup.rb +79 -0
- data/lib/sportdb/parser/lexer-on_prop_misc.rb +123 -0
- data/lib/sportdb/parser/lexer-on_prop_penalties.rb +40 -0
- data/lib/sportdb/parser/lexer-on_round_def.rb +37 -0
- data/lib/sportdb/parser/lexer-on_top.rb +133 -0
- data/lib/sportdb/parser/lexer-prep_doc.rb +131 -0
- data/lib/sportdb/parser/lexer-prep_line.rb +63 -0
- data/lib/sportdb/parser/lexer-tokenize.rb +468 -0
- data/lib/sportdb/parser/lexer.rb +122 -1376
- data/lib/sportdb/parser/lexer_buffer.rb +8 -37
- data/lib/sportdb/parser/lexer_token.rb +126 -0
- data/lib/sportdb/parser/parse_tree--core.rb +29 -0
- data/lib/sportdb/parser/parse_tree-match.rb +309 -0
- data/lib/sportdb/parser/parse_tree-props.rb +233 -0
- data/lib/sportdb/parser/parse_tree.rb +202 -0
- data/lib/sportdb/parser/parser-top.rb +102 -0
- data/lib/sportdb/parser/parser.rb +1253 -1392
- data/lib/sportdb/parser/token-date--helpers.rb +130 -0
- data/lib/sportdb/parser/token-date--names.rb +108 -0
- data/lib/sportdb/parser/token-date.rb +20 -192
- data/lib/sportdb/parser/token-date_duration.rb +8 -27
- data/lib/sportdb/parser/token-geo.rb +16 -16
- data/lib/sportdb/parser/token-goals--helpers.rb +114 -0
- data/lib/sportdb/parser/token-goals.rb +101 -255
- data/lib/sportdb/parser/token-group.rb +8 -22
- data/lib/sportdb/parser/token-prop.rb +178 -124
- data/lib/sportdb/parser/token-prop_name.rb +48 -39
- data/lib/sportdb/parser/token-round.rb +21 -35
- data/lib/sportdb/parser/token-score--helpers.rb +189 -0
- data/lib/sportdb/parser/token-score.rb +9 -393
- data/lib/sportdb/parser/token-score_full.rb +331 -0
- data/lib/sportdb/parser/token-status.rb +44 -46
- data/lib/sportdb/parser/token-status_inline.rb +112 -0
- data/lib/sportdb/parser/token-text.rb +41 -31
- data/lib/sportdb/parser/token-time.rb +29 -26
- data/lib/sportdb/parser/token.rb +90 -158
- data/lib/sportdb/parser/version.rb +2 -2
- data/lib/sportdb/parser.rb +88 -62
- metadata +27 -9
- data/lib/sportdb/parser/blocktxt.rb +0 -99
- data/lib/sportdb/parser/lexer_tty.rb +0 -111
- data/lib/sportdb/parser/racc_parser.rb +0 -88
- data/lib/sportdb/parser/racc_tree.rb +0 -557
- data/lib/sportdb/parser/token-table.rb +0 -149
- data/lib/sportdb/parser/token_helpers.rb +0 -92
- /data/lib/sportdb/parser/{parser_runtime.rb → parser-runtime.rb} +0 -0
|
@@ -21,7 +21,7 @@ GEO_TEXT_RE = %r{
|
|
|
21
21
|
# opt 1 - start with alpha
|
|
22
22
|
\p{L}+ ## all unicode letters (e.g. [a-z])
|
|
23
23
|
|
|
|
24
|
-
# opt 2 - start with num!! -
|
|
24
|
+
# opt 2 - start with num!! -
|
|
25
25
|
\d+ # check for num lookahead (MUST be space or dot)
|
|
26
26
|
## MAY be followed by (optional space) !
|
|
27
27
|
## MUST be follow by a to z!!!!
|
|
@@ -37,11 +37,11 @@ GEO_TEXT_RE = %r{
|
|
|
37
37
|
|
|
38
38
|
##
|
|
39
39
|
## todo/check - find a different "more intuitive" regex/rule if possible?
|
|
40
|
-
## for single spaces only (and _/ MUST not be surround by spaces)
|
|
40
|
+
## for single spaces only (and _/ MUST not be surround by spaces)
|
|
41
41
|
|
|
42
|
-
(?:
|
|
42
|
+
(?:
|
|
43
43
|
(?:
|
|
44
|
-
[ ]? # only single (inline) space allowed - double spaces are breaks!!!
|
|
44
|
+
[ ]? # only single (inline) space allowed - double spaces are breaks!!!
|
|
45
45
|
(?:
|
|
46
46
|
\p{L} | \d | [.&'°]
|
|
47
47
|
|
|
|
@@ -64,7 +64,7 @@ GEO_TEXT_RE = %r{
|
|
|
64
64
|
## Ost-Berlin (Walter-Ulbricht)
|
|
65
65
|
## Athinai (OAKA - Maroussi)
|
|
66
66
|
##
|
|
67
|
-
## or Valencia (Spain) or Solna
|
|
67
|
+
## or Valencia (Spain) or Solna
|
|
68
68
|
(?:
|
|
69
69
|
[ ]
|
|
70
70
|
\(
|
|
@@ -93,20 +93,14 @@ GEO_TEXT_RE = %r{
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
GEO_BASICS_RE = %r{
|
|
97
|
-
(?<spaces> [ ]{2,}) |
|
|
98
|
-
(?<space> [ ])
|
|
99
|
-
|
|
|
100
|
-
(?<sym> [,›>\[] )
|
|
101
|
-
}ix
|
|
102
96
|
|
|
103
97
|
|
|
104
98
|
## note - add "hacky" check for comma that is followed by a prop(erty)
|
|
105
99
|
##
|
|
106
100
|
## make sure to NOT match
|
|
107
101
|
## props e.g. att: 18000
|
|
108
|
-
## July 10 @ Paris, Parc des Princes, att: 18000
|
|
109
|
-
## July 10 @ Paris, Parc des Princes, att: 18000
|
|
102
|
+
## July 10 @ Paris, Parc des Princes, att: 18000
|
|
103
|
+
## July 10 @ Paris, Parc des Princes, att: 18000
|
|
110
104
|
##
|
|
111
105
|
|
|
112
106
|
|
|
@@ -115,18 +109,24 @@ GEO_END_RE = %r{
|
|
|
115
109
|
,
|
|
116
110
|
)
|
|
117
111
|
## POSITIVE lookahead for props
|
|
118
|
-
|
|
112
|
+
## todo/fix - use generic [a-z]+ - why? why not?
|
|
113
|
+
(?=
|
|
119
114
|
[ ]* ## optional spaces
|
|
120
|
-
(?:
|
|
115
|
+
(?: attendance|att
|
|
116
|
+
| referee?s|refs?
|
|
117
|
+
)
|
|
121
118
|
:
|
|
122
119
|
)
|
|
123
120
|
}ix
|
|
124
121
|
|
|
125
122
|
|
|
123
|
+
|
|
124
|
+
|
|
126
125
|
GEO_RE = Regexp.union(
|
|
126
|
+
SPACES_RE,
|
|
127
127
|
GEO_END_RE,
|
|
128
|
-
GEO_BASICS_RE,
|
|
129
128
|
GEO_TEXT_RE,
|
|
129
|
+
/ (?<sym> [,›>\[▪] ) /x,
|
|
130
130
|
ANY_RE,
|
|
131
131
|
)
|
|
132
132
|
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module SportDb
|
|
2
|
+
class Lexer
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def self._build_goal_minute( m )
|
|
7
|
+
minute = {}
|
|
8
|
+
|
|
9
|
+
minute[:m] = m[:value].to_i(10) ## always required
|
|
10
|
+
|
|
11
|
+
## stoppage/injury time (offset)
|
|
12
|
+
minute[:offset] = m[:value2].to_i(10) if m[:value2]
|
|
13
|
+
|
|
14
|
+
minute[:og] = true if m[:og]
|
|
15
|
+
minute[:pen] = true if m[:pen]
|
|
16
|
+
minute[:freekick] = true if m[:fk]
|
|
17
|
+
minute[:header] = true if m[:hdr]
|
|
18
|
+
|
|
19
|
+
minute[:secs] = m[:secs].to_i(10) if m[:secs]
|
|
20
|
+
|
|
21
|
+
minute
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self._build_goal_minute_na( m )
|
|
25
|
+
minute = {}
|
|
26
|
+
|
|
27
|
+
minute[:m] = '?' ## or use nil or 999 or -1 or ???
|
|
28
|
+
|
|
29
|
+
minute[:og] = true if m[:og]
|
|
30
|
+
minute[:pen] = true if m[:pen]
|
|
31
|
+
minute[:freekick] = true if m[:fk]
|
|
32
|
+
minute[:header] = true if m[:hdr]
|
|
33
|
+
|
|
34
|
+
minute
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def self._build_minute( m )
|
|
40
|
+
minute = {}
|
|
41
|
+
minute[:m] = m[:value].to_i(10) ## always required
|
|
42
|
+
|
|
43
|
+
## stoppage/injury time (offset)
|
|
44
|
+
minute[:offset] = m[:value2].to_i(10) if m[:value2]
|
|
45
|
+
|
|
46
|
+
minute
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def self._build_goal_count( m )
|
|
51
|
+
count = {}
|
|
52
|
+
count[:count] = m[:value].to_i(10) if m[:value]
|
|
53
|
+
count[:og] = m[:og_value] ? m[:og_value].to_i(10) : 1 if m[:og] ## check flag
|
|
54
|
+
count[:pen] = m[:pen_value] ? m[:pen_value].to_i(10) : 1 if m[:pen] ## check flag
|
|
55
|
+
count
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self._build_goal_type( m )
|
|
59
|
+
goal = {}
|
|
60
|
+
goal[:og] = true if m[:og]
|
|
61
|
+
goal[:pen] = true if m[:pen]
|
|
62
|
+
goal[:freekick] = true if m[:fk]
|
|
63
|
+
goal[:header] = true if m[:hdr]
|
|
64
|
+
goal
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _build_goal_minute( m ) self.class._build_goal_minute( m ); end
|
|
69
|
+
def _build_goal_minute_na( m ) self.class._build_goal_minute_na( m ); end
|
|
70
|
+
def _build_minute( m ) self.class._build_minute( m ); end
|
|
71
|
+
def _build_goal_count( m ) self.class._build_goal_count( m ); end
|
|
72
|
+
def _build_goal_type( m ) self.class._build_goal_type( m ); end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
###
|
|
79
|
+
# parse helpers
|
|
80
|
+
|
|
81
|
+
def self._parse_goal_minute( str )
|
|
82
|
+
## note - strip - leading/trailing spaces
|
|
83
|
+
m = GOAL_MINUTE_RE.match( str.strip )
|
|
84
|
+
if m && m.pre_match == '' && m.post_match == ''
|
|
85
|
+
_build_goal_minute( m )
|
|
86
|
+
elsif m
|
|
87
|
+
## note - match BUT not anchored to start and end-of-string!!!
|
|
88
|
+
## report, error somehow??
|
|
89
|
+
nil
|
|
90
|
+
else
|
|
91
|
+
nil ## no match - return nil
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self._parse_goal_count( str )
|
|
96
|
+
## note - strip - leading/trailing spaces
|
|
97
|
+
m = GOAL_COUNT_RE.match( str.strip )
|
|
98
|
+
if m && m.pre_match == '' && m.post_match == ''
|
|
99
|
+
_build_goal_count( m )
|
|
100
|
+
elsif m
|
|
101
|
+
## note - match BUT not anchored to start and end-of-string!!!
|
|
102
|
+
## report, error somehow??
|
|
103
|
+
nil
|
|
104
|
+
else
|
|
105
|
+
nil ## no match - return nil
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
end # class Lexer
|
|
114
|
+
end # module SportDb
|
|
@@ -3,32 +3,13 @@ class Lexer
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
######################################################
|
|
6
|
-
## goal mode
|
|
6
|
+
## goal mode
|
|
7
|
+
## note - must be enclosed in ()!!!
|
|
7
8
|
##
|
|
8
|
-
## note - must be enclosed in ()!!!
|
|
9
9
|
## todo - add () in basics - why? why not?
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
## todo/fix - split up BASICS!!!
|
|
15
|
-
## break out SPACES_RE for general reuse!!!
|
|
16
|
-
## makes it easier to use "custom" symbols (<sym>)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
GOAL_BASICS_RE = %r{
|
|
20
|
-
(?<spaces> [ ]{2,}) |
|
|
21
|
-
(?<space> [ ])
|
|
22
|
-
|
|
|
23
|
-
(?<sym>
|
|
24
|
-
[;,)] ## add (-) dash too - why? why not?
|
|
25
|
-
)
|
|
26
|
-
}ix
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
13
|
|
|
33
14
|
## note - assume lines starting with opening ( are goal lines!!!!
|
|
34
15
|
## note - use \A (instead of ^) - \A strictly matches the start of the string.
|
|
@@ -39,37 +20,25 @@ GOAL_BASICS_RE = %r{
|
|
|
39
20
|
## todo/fix -- exclude (a), (h), (n) - TEAM_AWAY, TEAM_HOME, TEAM_NEUTRAL tokens!!
|
|
40
21
|
|
|
41
22
|
START_GOAL_LINE_RE = %r{
|
|
42
|
-
\A
|
|
43
|
-
[ ]* ## ignore leading spaces (if any)
|
|
23
|
+
\A
|
|
24
|
+
[ ]* ## ignore leading spaces (if any)
|
|
44
25
|
\(
|
|
45
26
|
|
|
46
27
|
# check NEGATIVE lookahead
|
|
47
|
-
(?!
|
|
28
|
+
(?!
|
|
48
29
|
## exclude (a), (h), (n)
|
|
49
30
|
## TEAM_AWAY, TEAM_HOME, TEAM_NEUTRAL
|
|
50
|
-
(?: a|h|n )
|
|
51
|
-
\)
|
|
31
|
+
(?: a|h|n )
|
|
32
|
+
\)
|
|
52
33
|
)
|
|
53
34
|
|
|
54
35
|
}xi
|
|
55
36
|
|
|
56
|
-
=begin
|
|
57
|
-
# check NEGATIVE lookahead
|
|
58
|
-
(?!
|
|
59
|
-
## exclude ord
|
|
60
|
-
(?: \d+ \))
|
|
61
|
-
|
|
|
62
|
-
## exclude score - goal_line_alt!!!
|
|
63
|
-
(?: [ ]* \b
|
|
64
|
-
\d-\d ## score e.g. 1-0
|
|
65
|
-
\b )
|
|
66
|
-
)
|
|
67
|
-
=end
|
|
68
37
|
|
|
69
38
|
|
|
70
39
|
#############
|
|
71
40
|
## check for goal compat(ility) "legacy" line
|
|
72
|
-
## e.g.
|
|
41
|
+
## e.g.
|
|
73
42
|
## (6' Puskás 0-1, 9' Czibor 0-2, 11' Morlock 1-2, 18' Rahn 2-2,
|
|
74
43
|
## 84' Rahn 3-2)
|
|
75
44
|
## (6 Puskás 0-1, 9 Czibor 0-2, 11 Morlock 1-2, 18 Rahn 2-2,
|
|
@@ -78,53 +47,50 @@ START_GOAL_LINE_RE = %r{
|
|
|
78
47
|
|
|
79
48
|
START_GOAL_LINE_COMPAT_RE = %r{
|
|
80
49
|
\A
|
|
81
|
-
[ ]* ## ignore leading spaces (if any)
|
|
82
|
-
\(
|
|
83
|
-
|
|
50
|
+
[ ]* ## ignore leading spaces (if any)
|
|
51
|
+
\(
|
|
52
|
+
|
|
84
53
|
## (i) check NEGATIVE lookahead
|
|
85
|
-
## exclude score e.g. 1-1 etc.
|
|
54
|
+
## exclude score e.g. 1-1 etc.
|
|
86
55
|
(?! [ ]* \b \d-\d \b)
|
|
87
56
|
|
|
88
|
-
## (ii) check POSITIVE lookahead
|
|
57
|
+
## (ii) check POSITIVE lookahead
|
|
89
58
|
(?= [ ]*
|
|
90
59
|
\d{1,3}
|
|
91
60
|
'? ## optional minute marker
|
|
92
61
|
(?: \+
|
|
93
|
-
\d{1,2}
|
|
62
|
+
\d{1,2}
|
|
94
63
|
'? ## optional minute marker
|
|
95
|
-
)?
|
|
96
|
-
)
|
|
64
|
+
)?
|
|
65
|
+
)
|
|
97
66
|
}xi
|
|
98
67
|
|
|
99
68
|
|
|
100
69
|
|
|
101
70
|
###
|
|
102
71
|
## check for goal line (alternate syntax)
|
|
103
|
-
## (1-0 Player, 1-1 Player, ...)
|
|
104
|
-
# must start-off OR yes, include score
|
|
105
|
-
##
|
|
106
|
-
## note - allow "centered" style e.g.
|
|
107
|
-
## ( Player 44' (p) 1-0
|
|
72
|
+
## (1-0 Player, 1-1 Player, ...)
|
|
73
|
+
# must start-off OR yes, include score
|
|
74
|
+
##
|
|
75
|
+
## note - allow "centered" style e.g.
|
|
76
|
+
## ( Player 44' (p) 1-0
|
|
108
77
|
## 1-1 Player 64' )
|
|
109
78
|
START_GOAL_LINE_ALT_RE = %r{
|
|
110
79
|
\A
|
|
111
|
-
[ ]* ## ignore leading spaces (if any)
|
|
112
|
-
\(
|
|
113
|
-
|
|
114
|
-
# check POSITIVE lookahead
|
|
115
|
-
(?= .*? ## note - non-greedy
|
|
116
|
-
\b \d-\d \b ## score e.g. 0-1
|
|
117
|
-
)
|
|
80
|
+
[ ]* ## ignore leading spaces (if any)
|
|
81
|
+
\(
|
|
82
|
+
|
|
83
|
+
# check POSITIVE lookahead
|
|
84
|
+
(?= .*? ## note - non-greedy
|
|
85
|
+
\b \d-\d \b ## score e.g. 0-1
|
|
86
|
+
)
|
|
118
87
|
}xi
|
|
119
88
|
|
|
120
89
|
|
|
121
90
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
-[ ]*;
|
|
126
|
-
)
|
|
127
|
-
}x
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
128
94
|
|
|
129
95
|
###
|
|
130
96
|
# note - alternate goal separator dash (-) MUST have leading and trailing space!!!
|
|
@@ -132,10 +98,10 @@ GOAL_NONE_RE = %r{ (?<goals_none>
|
|
|
132
98
|
# e.g. (Metzger - Krämer (2), Cichy, Rahn)
|
|
133
99
|
# (Brunnenmeier 17 - Gerwien 74)
|
|
134
100
|
# (Brunnenmeier - Gerwien)
|
|
135
|
-
# that is, NOT allowed
|
|
101
|
+
# that is, NOT allowed
|
|
136
102
|
# e.g. (Metzger 83-Krämer 29, 88, Cichy 33, Rahn 37)
|
|
137
103
|
# (Brunnenmeier 17-Gerwien 74)
|
|
138
|
-
# (Brunnenmeier-Gerwien)
|
|
104
|
+
# (Brunnenmeier-Gerwien)
|
|
139
105
|
#
|
|
140
106
|
# note - allow split by - e.g.
|
|
141
107
|
# Frankfurt 4-2 Schalke (Kreß 45, Solz 55, Trimhold 58, Huberts 73 p -
|
|
@@ -151,11 +117,11 @@ GOAL_SEP_ALT_RE = %r{
|
|
|
151
117
|
|
|
152
118
|
|
|
153
119
|
## e.g. (2)
|
|
154
|
-
## (2/p), (2/pen.), (3/2p), (3/ 2 pen.)
|
|
120
|
+
## (2/p), (2/pen.), (3/2p), (3/ 2 pen.)
|
|
155
121
|
## -or- (2,1pen), (3, 2 pens)
|
|
156
|
-
##
|
|
157
|
-
## (p), (pen.) (2 pen.), (2p)
|
|
158
|
-
## (og), (o.g.),
|
|
122
|
+
##
|
|
123
|
+
## (p), (pen.) (2 pen.), (2p)
|
|
124
|
+
## (og), (o.g.),
|
|
159
125
|
## (2og), (2 o.g.), (2ogs)
|
|
160
126
|
#
|
|
161
127
|
##
|
|
@@ -173,8 +139,8 @@ GOAL_COUNT_RE = %r{
|
|
|
173
139
|
## opt own goals (og)
|
|
174
140
|
(?<og>
|
|
175
141
|
(?: (?<og_value> \d{1,2}) [ ]? )?
|
|
176
|
-
(?:ogs?|o\.g\.|o)
|
|
177
|
-
)
|
|
142
|
+
(?:ogs?|o\.g\.|o)
|
|
143
|
+
)
|
|
178
144
|
|
|
|
179
145
|
## opt fallback - classic count/number
|
|
180
146
|
(?: (?<value> [1-9])
|
|
@@ -185,50 +151,19 @@ GOAL_COUNT_RE = %r{
|
|
|
185
151
|
(?:pens|pen\.?|p)
|
|
186
152
|
)?
|
|
187
153
|
)
|
|
188
|
-
)
|
|
154
|
+
)
|
|
189
155
|
\)
|
|
190
156
|
)}ix
|
|
191
157
|
|
|
192
158
|
|
|
193
159
|
|
|
194
160
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
## minute variant for N/A not/available
|
|
198
|
-
## todo/check - find a better syntax - why? why not?
|
|
199
|
-
##
|
|
200
|
-
## note "??".to_i(10) returns 0 or
|
|
201
|
-
## "__".to_i(10) returns 0
|
|
202
|
-
## quick hack - assume 0 for n/a for now
|
|
203
|
-
|
|
204
|
-
MINUTE_NA_RE = %r{
|
|
205
|
-
(?<minute>
|
|
206
|
-
(?<=[ (]) # positive lookbehind for space or opening
|
|
207
|
-
(?<value> \?{2} | _{2} )
|
|
208
|
-
' ## must have minute marker!!!!
|
|
209
|
-
)
|
|
210
|
-
}ix
|
|
211
|
-
|
|
212
|
-
=begin
|
|
213
|
-
MINUTE_RE = %r{
|
|
214
|
-
(?<minute>
|
|
215
|
-
(?<=[ (]) # positive lookbehind for space or opening ( e.g. (61') required
|
|
216
|
-
# todo - add more lookbehinds e.g. ,) etc. - why? why not?
|
|
217
|
-
(?<value>\d{1,3}) ## constrain numbers to 0 to 999!!!
|
|
218
|
-
(?: \+
|
|
219
|
-
(?<value2>\d{1,3})
|
|
220
|
-
)?
|
|
221
|
-
' ## must have minute marker!!!!
|
|
222
|
-
)
|
|
223
|
-
}ix
|
|
224
|
-
=end
|
|
225
|
-
|
|
226
|
-
|
|
227
161
|
##
|
|
228
162
|
## note - inline \b check in MINUTE_RE excludes
|
|
229
|
-
## 85pen or 90+4pen or 38p
|
|
163
|
+
## 85pen or 90+4pen or 38p
|
|
164
|
+
## (possible and NOT excluded in GOAL_MINUTE_RE !!!)
|
|
230
165
|
##
|
|
231
|
-
## minute with optional stoppage
|
|
166
|
+
## minute with optional stoppage (offset)
|
|
232
167
|
|
|
233
168
|
MINUTE_RE = %r{
|
|
234
169
|
(?<minute>
|
|
@@ -236,19 +171,59 @@ MINUTE_RE = %r{
|
|
|
236
171
|
(?<value>\d{1,3}) ## constrain numbers to 0 to 999!!!
|
|
237
172
|
\b
|
|
238
173
|
'? ## optional minute marker
|
|
239
|
-
|
|
240
|
-
(?: \+ (?<value2>\d{1,2})
|
|
241
|
-
\b
|
|
174
|
+
|
|
175
|
+
(?: \+ (?<value2>\d{1,2})
|
|
176
|
+
\b
|
|
242
177
|
'? ## optional minute marker
|
|
243
178
|
)?
|
|
244
|
-
|
|
245
179
|
)
|
|
246
180
|
}ix
|
|
247
181
|
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
##
|
|
185
|
+
## keep separate? or add simply inside GOAL_MINUTE_RE - why? why not?
|
|
186
|
+
## fix-fix-fix - move into GOAL_MINUTE_RE !!!
|
|
187
|
+
|
|
188
|
+
GOAL_MINUTE_NA_RE = %r{
|
|
189
|
+
(?<goal_minute_na>
|
|
190
|
+
|
|
191
|
+
# positive lookbehind
|
|
192
|
+
(?<=[ ,;])
|
|
193
|
+
|
|
194
|
+
(?<value> \?{1,2})
|
|
195
|
+
'? ## optional minute marker
|
|
196
|
+
## note - add goal minute qualifiers here inline!!!
|
|
197
|
+
(?:
|
|
198
|
+
(?: [ ]? (?<og> (?: \((?:og|o\.g\.|o)\)) ## allow (og)
|
|
199
|
+
|
|
|
200
|
+
(?: (?:og|o\.g\.|o)) ## allow plain og
|
|
201
|
+
)
|
|
202
|
+
)
|
|
203
|
+
|
|
|
204
|
+
(?: [ ]? (?<pen> (?: \((?:pen\.?|p)\)) ## allow ()
|
|
205
|
+
|
|
|
206
|
+
(?: (?:pen\.?|p))
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
|
|
|
210
|
+
## add experimental header qualifier
|
|
211
|
+
(?: [ ]? (?<hdr> \( (?:hdr\.?|h ) \) | (?: hdr\.?|h ) ))
|
|
212
|
+
|
|
|
213
|
+
## add experimental free kick qualifier
|
|
214
|
+
(?: [ ]? (?<fk> \( (?:fk\.?|f ) \) | (?: fk\.?|f) ))
|
|
215
|
+
)?
|
|
216
|
+
|
|
217
|
+
## note - check positive lookahead
|
|
218
|
+
(?=[ ,;)]|$)
|
|
219
|
+
)
|
|
220
|
+
}ix
|
|
221
|
+
|
|
222
|
+
|
|
248
223
|
## goal types
|
|
249
224
|
# (pen.) or (pen) or (p.) or (p)
|
|
250
225
|
## (o.g.) or (og)
|
|
251
|
-
## todo/check - keep case-insensitive
|
|
226
|
+
## todo/check - keep case-insensitive
|
|
252
227
|
## or allow OG or P or PEN or
|
|
253
228
|
## only lower case - why? why not?
|
|
254
229
|
##
|
|
@@ -260,12 +235,12 @@ GOAL_MINUTE_RE = %r{
|
|
|
260
235
|
\b
|
|
261
236
|
(?<value>\d{1,3}) ## constrain numbers to 0 to 999!!!
|
|
262
237
|
'? ## optional minute marker
|
|
263
|
-
|
|
238
|
+
|
|
264
239
|
(?: \+ (?<value2>\d{1,2})
|
|
265
240
|
'? ## optional minute marker
|
|
266
|
-
)?
|
|
267
|
-
|
|
268
|
-
## note - add goal minute qualifiers here inline!!!
|
|
241
|
+
)?
|
|
242
|
+
|
|
243
|
+
## note - add goal minute qualifiers here inline!!!
|
|
269
244
|
(?:
|
|
270
245
|
(?: [ ]? (?<og> (?: \((?:og|o\.g\.|o)\)) ## allow (og)
|
|
271
246
|
|
|
|
@@ -276,7 +251,7 @@ GOAL_MINUTE_RE = %r{
|
|
|
276
251
|
(?: [ ]? (?<pen> (?: \((?:pen\.?|p)\)) ## allow ()
|
|
277
252
|
|
|
|
278
253
|
(?: (?:pen\.?|p))
|
|
279
|
-
)
|
|
254
|
+
)
|
|
280
255
|
)
|
|
281
256
|
|
|
|
282
257
|
## add experimental header qualifier
|
|
@@ -287,45 +262,33 @@ GOAL_MINUTE_RE = %r{
|
|
|
287
262
|
)?
|
|
288
263
|
|
|
289
264
|
## add experimental seconds
|
|
290
|
-
## e.g. (95 secs) or (95sec) etc.
|
|
265
|
+
## e.g. (95 secs) or (95sec) etc.
|
|
291
266
|
(?: [ ]* \(
|
|
292
267
|
(?<secs>\d{1,3})
|
|
293
268
|
[ ]?secs?
|
|
294
|
-
\)
|
|
269
|
+
\)
|
|
295
270
|
)?
|
|
296
271
|
)
|
|
297
272
|
|
|
298
|
-
## note - check positive lookahead
|
|
299
|
-
(?=[ ,;)]|$)
|
|
273
|
+
## note - check positive lookahead
|
|
274
|
+
(?=[ ,;)]|$)
|
|
300
275
|
}ix
|
|
301
276
|
|
|
302
277
|
|
|
303
278
|
|
|
304
279
|
|
|
305
280
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
GOAL_BASICS_RE,
|
|
309
|
-
GOAL_NONE_RE,
|
|
310
|
-
GOAL_MINUTE_RE,
|
|
311
|
-
GOAL_COUNT_RE,
|
|
312
|
-
## MINUTE_NA_RE, ## note - add/allow not/available (n/a,na) minutes hack for now
|
|
313
|
-
## GOAL_OG_RE, GOAL_PEN_RE,
|
|
314
|
-
## SCORE_RE, ## add back in v2 (level 3) or such!!
|
|
315
|
-
PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
|
|
316
|
-
GOAL_SEP_ALT_RE,
|
|
317
|
-
## todo/fix - add ANY_RE !!!!
|
|
318
|
-
)
|
|
319
|
-
|
|
281
|
+
###
|
|
282
|
+
## more regex for goal alt
|
|
320
283
|
|
|
321
284
|
|
|
322
285
|
GOAL_TYPE_RE = %r{
|
|
323
286
|
(?<goal_type>
|
|
324
287
|
\(
|
|
325
288
|
(?:
|
|
326
|
-
(?<og> og|o\.g\.|o )
|
|
289
|
+
(?<og> og|o\.g\.|o )
|
|
327
290
|
|
|
|
328
|
-
(?<pen> pen\.?|p )
|
|
291
|
+
(?<pen> pen\.?|p )
|
|
329
292
|
|
|
|
330
293
|
## add experimental header qualifier
|
|
331
294
|
(?<hdr> hdr\.?|h )
|
|
@@ -338,123 +301,6 @@ GOAL_TYPE_RE = %r{
|
|
|
338
301
|
|
|
339
302
|
|
|
340
303
|
|
|
341
|
-
GOAL_ALT_RE = Regexp.union(
|
|
342
|
-
GOAL_BASICS_RE,
|
|
343
|
-
SCORE_RE, ## e.g. 1-0, 0-1, etc.
|
|
344
|
-
GOAL_MINUTE_RE,
|
|
345
|
-
GOAL_TYPE_RE,
|
|
346
|
-
PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
|
|
347
|
-
## todo/fix - add ANY_RE !!!!
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
GOAL_COMPAT_RE = Regexp.union(
|
|
351
|
-
GOAL_BASICS_RE,
|
|
352
|
-
SCORE_RE, ## e.g. 1-0, 0-1, etc.
|
|
353
|
-
MINUTE_RE, ## note - matches minute e.g. 92, 7, 7' 7+3, 46+, etc.
|
|
354
|
-
GOAL_TYPE_RE,
|
|
355
|
-
PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
|
|
356
|
-
## todo/fix - add ANY_RE !!!!
|
|
357
|
-
)
|
|
358
|
-
|
|
359
|
-
=begin
|
|
360
|
-
## note - leave out n/a minute in goals - make minutes optional!!!
|
|
361
|
-
PROP_GOAL_RE = Regexp.union(
|
|
362
|
-
GOAL_BASICS_RE,
|
|
363
|
-
MINUTE_RE,
|
|
364
|
-
## MINUTE_NA_RE, ## note - add/allow not/available (n/a,na) minutes hack for now
|
|
365
|
-
GOAL_OG_RE, GOAL_PEN_RE,
|
|
366
|
-
SCORE_RE,
|
|
367
|
-
PROP_NAME_RE, ## note - (re)use prop name for now for (player) name
|
|
368
|
-
)
|
|
369
|
-
=end
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
def self._parse_goal_minute( str )
|
|
375
|
-
## note - strip - leading/trailing spaces
|
|
376
|
-
m = GOAL_MINUTE_RE.match( str.strip )
|
|
377
|
-
if m && m.pre_match == '' && m.post_match == ''
|
|
378
|
-
_build_goal_minute( m )
|
|
379
|
-
elsif m
|
|
380
|
-
## note - match BUT not anchored to start and end-of-string!!!
|
|
381
|
-
## report, error somehow??
|
|
382
|
-
nil
|
|
383
|
-
else
|
|
384
|
-
nil ## no match - return nil
|
|
385
|
-
end
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
def self._build_goal_minute( m )
|
|
390
|
-
minute = {}
|
|
391
|
-
|
|
392
|
-
minute[:m] = m[:value].to_i(10) ## always required
|
|
393
|
-
|
|
394
|
-
## stoppage/injury time (offset)
|
|
395
|
-
minute[:offset] = m[:value2].to_i(10) if m[:value2]
|
|
396
|
-
|
|
397
|
-
minute[:og] = true if m[:og]
|
|
398
|
-
minute[:pen] = true if m[:pen]
|
|
399
|
-
minute[:freekick] = true if m[:fk]
|
|
400
|
-
minute[:header] = true if m[:hdr]
|
|
401
|
-
|
|
402
|
-
minute[:secs] = m[:secs].to_i(10) if m[:secs]
|
|
403
|
-
|
|
404
|
-
minute
|
|
405
|
-
end
|
|
406
|
-
def _build_goal_minute( m ) self.class._build_goal_minute( m ); end
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
def self._build_minute( m )
|
|
410
|
-
minute = {}
|
|
411
|
-
minute[:m] = m[:value].to_i(10) ## always required
|
|
412
|
-
|
|
413
|
-
## stoppage/injury time (offset)
|
|
414
|
-
minute[:offset] = m[:value2].to_i(10) if m[:value2]
|
|
415
|
-
|
|
416
|
-
minute
|
|
417
|
-
end
|
|
418
|
-
def _build_minute( m ) self.class._build_minute( m ); end
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
def self._parse_goal_count( str )
|
|
423
|
-
## note - strip - leading/trailing spaces
|
|
424
|
-
m = GOAL_COUNT_RE.match( str.strip )
|
|
425
|
-
if m && m.pre_match == '' && m.post_match == ''
|
|
426
|
-
_build_goal_count( m )
|
|
427
|
-
elsif m
|
|
428
|
-
## note - match BUT not anchored to start and end-of-string!!!
|
|
429
|
-
## report, error somehow??
|
|
430
|
-
nil
|
|
431
|
-
else
|
|
432
|
-
nil ## no match - return nil
|
|
433
|
-
end
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
def self._build_goal_count( m )
|
|
437
|
-
count = {}
|
|
438
|
-
count[:count] = m[:value].to_i(10) if m[:value]
|
|
439
|
-
count[:og] = m[:og_value] ? m[:og_value].to_i(10) : 1 if m[:og] ## check flag
|
|
440
|
-
count[:pen] = m[:pen_value] ? m[:pen_value].to_i(10) : 1 if m[:pen] ## check flag
|
|
441
|
-
count
|
|
442
|
-
end
|
|
443
|
-
def _build_goal_count( m ) self.class._build_goal_count( m ); end
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
def self._build_goal_type( m )
|
|
449
|
-
goal = {}
|
|
450
|
-
goal[:og] = true if m[:og]
|
|
451
|
-
goal[:pen] = true if m[:pen]
|
|
452
|
-
goal[:freekick] = true if m[:fk]
|
|
453
|
-
goal[:header] = true if m[:hdr]
|
|
454
|
-
goal
|
|
455
|
-
end
|
|
456
|
-
def _build_goal_type( m ) self.class._build_goal_type( m ); end
|
|
457
|
-
|
|
458
304
|
|
|
459
305
|
end # class Lexer
|
|
460
306
|
end # module SportDb
|