Note - you can try the default/standard parser (& tokenizer) for the Football.TXT (match schedule, results, line-ups & more) format as (standalone) command-line tools.
For the tokenizer (lexer) try:
$ fbtok england/2019-20/1-premierleague.txt
and for the parser - outputing the (abstract) parse tree - try:
$ fbtree england/2019-20/1-premierleague.txt
Tip - to install the tools use:
$ gem install fbtok # (incl. fbtree and others)
You are welcome to comment on the default/standard Football.TXT format.
You can find samples for the Football.TXT format, level 1 in the /samples directory
and for level 2 in the /samples-l2 directory.
Why not use JSON, CSV, XML, YAML, SQL, your ‹format of choice here›? Why invent yet another (structured text) data format?
Excercise: Try to write by hand the round-by-round match schedule (with results) for the English Premier League? How do you enjoy writing the match schedule (for 20 teams with 38 rounds with 10 matches each) in JSON? in CSV? in XML? in SQL? in YAML?
Now retry using the new Football.TXT format / (structured text) data language designed to make hand-crafting
as easy as possible. See the difference?
Example - england/2025-26/1-premierleague.txt in Football.TXT:
▪ Matchday 1
Fri Aug 15
20:00 Liverpool FC v AFC Bournemouth 4-2 (1-0)
Sat Aug 16
12:30 Aston Villa FC v Newcastle United FC 0-0
15:00 Brighton & Hove Albion FC v Fulham FC 1-1 (0-0)
Sunderland AFC v West Ham United FC 3-0 (0-0)
Tottenham Hotspur FC v Burnley FC 3-0 (1-0)
17:30 Wolverhampton Wanderers FC v Manchester City FC 0-4 (0-2)
Sun Aug 17
14:00 Nottingham Forest FC v Brentford FC 3-1 (3-0)
Chelsea FC v Crystal Palace FC 0-0
16:30 Manchester United FC v Arsenal FC 0-1 (0-1)
Mon Aug 18
20:00 Leeds United FC v Everton FC 1-0 (0-0)
...
vs Example - 2025-26/en.1.json in Football.JSON:
"matches": [
{ "round": "Matchday 1", "date": "2025-08-15", "time": "20:00",
"team1": "Liverpool FC", "team2": "AFC Bournemouth", "score": {"ht": [1,0], "ft": [4,2]}
},
{ "round": "Matchday 1", "date": "2025-08-16", "time": "12:30",
"team1": "Aston Villa FC", "team2": "Newcastle United FC", "score": {"ft": [0,0]}
},
{ "round": "Matchday 1", "date": "2025-08-16", "time": "15:00",
"team1": "Brighton & Hove Albion FC", "team2": "Fulham FC", "score": {"ht": [0,0], "ft": [1,1]}
},
{ "round": "Matchday 1", "date": "2025-08-16", "time": "15:00",
"team1": "Sunderland AFC", "team2": "West Ham United FC", "score": {"ht": [0,0], "ft": [3,0]}
},
{ "round": "Matchday 1", "date": "2025-08-16", "time": "15:00",
"team1": "Tottenham Hotspur FC", "team2": "Burnley FC", "score": {"ht": [1,0], "ft": [3,0]}
},
{ "round": "Matchday 1", "date": "2025-08-16", "time": "17:30",
"team1": "Wolverhampton Wanderers FC", "team2": "Manchester City FC", "score": {"ht": [0,2], "ft": [0,4]}
},
{ "round": "Matchday 1", "date": "2025-08-17", "time": "14:00",
"team1": "Nottingham Forest FC", "team2": "Brentford FC", "score": {"ht": [3,0], "ft": [3,1]}
},
{ "round": "Matchday 1", "date": "2025-08-17", "time": "14:00",
"team1": "Chelsea FC", "team2": "Crystal Palace FC", "score": {"ft": [0,0]}
},
{ "round": "Matchday 1", "date": "2025-08-17", "time": "16:30",
"team1": "Manchester United FC", "team2": "Arsenal FC", "score": {"ht": [0,1], "ft": [0,1]}
},
{ "round": "Matchday 1", "date": "2025-08-18", "time": "20:00",
"team1": "Leeds United FC", "team2": "Everton FC", "score": {"ht": [0,0], "ft": [1,0]}
}, ...
]
Note: If you auto-generate your datasets and want to focus on easy machine-writing and machine-reading, see the Football.CSV format » :-).
The new Football.TXT format / data language for football match schedules (results, line-ups & more) using structured text offers you the best of both worlds, that is, 1) looks ‘n’ feels like free-form plain text - easy-to-read and easy-to-write - 2) but offers a 100-% data accuracy guarantee (when loading into SQL tables or exporting/converting into JSON, CSV, and friends, for example).
The Football.TXT format / data language also includes support for groups, matchdays, grounds, and much more. Example:
= World Cup 2022
Group A | Qatar Ecuador Senegal Netherlands
Group B | England Iran United States Wales
Group C | Argentina Saudi Arabia Mexico Poland
Group D | France Australia Denmark Tunisia
Group E | Spain Costa Rica Germany Japan
Group F | Belgium Canada Morocco Croatia
Group G | Brazil Serbia Switzerland Cameroon
Group H | Portugal Ghana Uruguay South Korea
Matchday 1 | Sun Nov 20
Matchday 2 | Mon Nov 21
Matchday 3 | Tue Nov 22
...
▪ Group A
Sun Nov 20
19:00 Qatar v Ecuador 0-2 (0-2) @ Al Bayt Stadium, Al Khor
(Enner Valencia 16'(p), 31')
Mon Nov 21
19:00 Senegal v Netherlands 0-2 (0-0) @ Al Thumama Stadium, Doha
(Cody Gakpo 84', Davy Klaassen 90'+9)
...
▪ Match for third place
Sat Dec 17
18:00 Croatia v Morocco 2-1 (2-1) @ Khalifa International Stadium, Al Rayyan
(Joško Gvardiol 7', Mislav Oršić 42'; Achraf Dari 9')
▪ Final
Sun Dec 18
18:00 Argentina v France 3-3 a.e.t. (2-2, 2-0) 4-2 pen. @ Lusail Iconic Stadium, Lusail
(Lionel Messi 23'(p), 108', Ángel Di María 36';
Kylian Mbappé 80'(p), 81', 118'(p))
Note - starting in 2026 the Football.TXT format is now split-up into levels.
Level 1 supports and includes match schedules with goal scorer lines BUT no team line-ups, sent-offs props and more.
Level 2 supports all of Level 1 plus team line-ups, sent-offs props and more.
Sample:
▪ Quarter-finals - 1st Leg
Tue Apr 1
20:45 FC Barcelona v Atlético Madrid 1-1 @ Camp Nou, Barcelona
(Neymar 71'; Diego 56')
20:45 Manchester United v Bayern München 1-1 @ Old Trafford, Manchester
(Vidić 58'; Schweinsteiger 67')
Wed Apr 2
20:45 Real Madrid v Borussia Dortmund 3-0 @ Santiago Bernabéu, Madrid
(Bale 3' Isco 27' Ronaldo 57')
20:45 Paris Saint-Germain v Chelsea FC 3-1 @ Parc des Princes, Paris
(Lavezzi 4' Luiz 61'og Pastore 90+3'; Hazard 27'pen)
For match fixtures (without results) you MUST separate two team names by - or v.
Examples:
Brazil - Mexico
Cameroon - Croatia
Cameroon v Brazil
Croatia v Mexico
For match results (i) you can separate two team names by - or v (same as fixtures) followed by the score (e.g. 0-0) or separate team names by the score.
Examples:
Atlético Mineiro v River Plate 3-0
Botafogo v Peñarol 5-0
Atlético Mineiro - River Plate 3-0
Botafogo - Peñarol 5-0
River Plate 0-0 Atlético Mineiro
Peñarol 3-1 Botafogo
For the after extra-time (aet) score or penalties formats, see the score format section.
Note - The “atomic” text unit in Football.TXT is NOT the classic word or identifier BUT a text run. If you want to break text runs use two (or more) spaces.
ARG BOL BRA => [:TEXT,"ARG"], [:TEXT,"BOL"], [:TEXT,"BRA"]
ARG BOL BRA => [:TEXT,"ARG BOL BRA"]
Fri Liverpool => [:TEXT,"Fri"], [:TEXT,"Liverpool"]
Fri Liverpool => [:TEXT,"Fri Liverpool"]
Matchday 1 => [:TEXT,"Matchday 1"]
1860 München => [:TEXT,"1860 München"]
...
Round lines (outlines) MUST start with ▪ (BLACK SMALL SQUARE) or :: (for ASCII-style) e.g.
▪ Quarter-finals - 1st Leg
▪ Group A
▪ Match for third place
...
To add stages in your match schedules and round lines (outlines) use:
▪ Matchday 1 # no stage (assumes regular season)
▪ Matchday 2
...
▪ Championship, Matchday 1 # Championship stage
▪ Championship, Matchday 2
...
▪ Europe, Matchday 1 # Europe stage
▪ Europe, Matchday 2
...
# -or-
▪ League, Matchday 1 # League stage
▪ League, Matchday 2
...
▪ Playoffs, Matchday 1 # Playoffs stage
▪ Playoffs, Matchday 2
...
▪ Finals, Round of 16 # Finals stage
▪ Finals, Quarterfinals
▪ Finals, Semifinals
▪ Finals, Final
Use the geo marker, that is, @ to start with adding “geo” names - that is, stadiums & grounds
and / or cities, countries and more.
Examples:
@ Stadio Olimpico, Roma
@ Arena Naţională, Bucureşti, Romania
@ Bucuresti, 23 August
@ Wien, Prater
@ Buenos Aires
@ Brasília
@ Arena Fonte Nova, Salvador
@ Arena Pantanal, Cuiabá
@ Estádio do Maracanã, Rio de Janeiro
...
Note - Geo names have their own (lexer) mode and, thus, you can (even) use dates
(e.g. 23 August) or more.
Use blank links as you wish to make the text look pretty, that is, easy-to-read and easy-to-write.
You can use # for comments. Example:
# Date Fri Aug/15 2025 - Sun May/24 2026 (282d)
# Teams 20
# Matches 380
# Hugo Lloris saved a penalty from Ricardo Rodríguez at 55'.
You can use HTML-style comments, that is, <!-- .. -->. Example:
<!--
1.AUSTRIA 3 2 0 1 6- 4 6
2.FRANCE 3 1 2 0 2- 1 5
3.NETHERLANDS 3 1 1 1 4- 4 4
4.Poland 3 0 1 2 3- 6 1
-->
Goal (scorer) lines MUST be enclosed with () and, thus, start with ( e.g.
(Neymar 71'; Diego 56')
(Lavezzi 4' Luiz 61'og Pastore 90+3'; Hazard 27'pen)
...
The Football.TXT Format Level 2 supports all of Level 1 plus adds:
<GROUP> | <TEAM> <TEAM> ...
Note - <GROUP>is a text run (<TEXT>) that MUST match the group matching formula that
incl. Group 1, Group 2, Group A, Group B, Group A1, Group A2, Group B1, Group B2, etc.
Examples:
Group A | Brazil Croatia Mexico Cameroon
Group B | Spain Netherlands Chile Australia
...
<ROUND> | <DATE> OR
<ROUND> | <DATE_PERIOD>
Note - <ROUND> is a text run (<TEXT>) that MUST match the round matching formula that
incl. Matchday 1, Matchday 2, Round 1, Round 2, Final, and many more.
Examples:
Matchday 1 | Thu Jun 12
Matchday 2 | Fri Jun 13
Matchday 3 | Sat Jun 14
...
Round of 16 | Sat Jun 28 - Tue Jul 1
Quarter-finals | Fri Jul 4 - Sat Jul 5
Semi-finals | Tue Jul 8 - Wed Jul 9
Match for third place | Sat Jul 12
Final | Sun Jul 13
What’s the point? If a match has no round header (in scope) than tools can use the round & match definitions to find a match by date lookup.
Property lines start with a team name followed by double colon (:)
for lineups or known property keywords / names (e.g. Penalties, Goals, Referee, etc.)
followd by double colon (:) for all other props.
Examples:
Yugoslavia: Soskic, Durkovic, Jusufi, Zanetic, Zebec, Perusic, Knez,
Jerkovic, Galic, Sekularac, Kostic
France: Lamia, Wendling, Rodzik, Marcel, Herbin, Ferrier, Heutte, Müller,
Wiesnieski, Stievenard, Vincent
Italy: Gianluigi Donnarumma - Alessandro Florenzi (Giovanni Di Lorenzo),
Leonardo Bonucci, Giorgio Chiellini, Leonardo Spinazzola -
Nicolò Barella, Jorge Frello Filho, Manuel Locatelli (Bryan Cristante) -
Domenico Berardi (Federico Bernardeschi), Ciro Immobile (Andrea Belotti),
Lorenzo Insigne (Federico Chiesa); Coach: Roberto Mancini
Turkey: Uğurcan Çakır - Mehmet Zeki Çelik, Merih Demiral, Çağlar Söyüncü,
Umut Meraş - Okay Yokuşlu (İrfan Can Kahveci) -
Kenan Karaman (Halil Dervişoğlu), Yusuf Yazıcı (Cengiz Ünder),
Ozan Tufan (Kaan Ayhan), Hakan Çalhanoğlu - Burak Yılmaz;
Coach: Şenol Güneş
Switzerland: Yann Sommer - Nico Elvedi, Manuel Akanji,
Ricardo Rodríguez (Admir Mehmedi 87') - Silvan Widmer (Kevin Mbabu 73'),
Remo Freuler, Granit Xhaka, Steven Zuber (Christian Fassnacht 79') -
Breel Embolo (Ruben Vargas 79'), Xherdan Shaqiri (Mario Gavranović 73'),
Haris Seferović (Fabian Schär 97'); Coach: Vladimir Petković
France: Hugo Lloris - Benjamin Pavard, Raphaël Varane,
Clément Lenglet (Kingsley Coman 46' (Marcus Thuram 111')),
Presnel Kimpembe, Adrien Rabiot -
Paul Pogba, N'Golo Kanté, Antoine Griezmann (Moussa Sissoko 88') -
Karim Benzema (Olivier Giroud 94'), Kylian Mbappé;
Coach: Didier Deschamps
Palmeiras: Marcos - Francisco Javier Arce (Evair 57'), Júnior Baiano,
Roque Júnior, Rogério, César Sampaio, Alex (75' Euller), Zinho,
Oséas, Paulo Nunes; trainer: Luiz Felipe Scolari
Deportivo Cali: Rafael Dudamel - John Wilmer Pérez (Herman Gaviria 84'),
Andrés Mosquera, Mario Yepez, Gerardo Bedoya, Martín Zapata,
Alexander Viveros, Arley Betancourt, Mayer Candelo (Freddy Hurtado 62'),
Geovanny Córdoba (Manuel Valencia 81'),
Victor Bonilla; trainer: José Hernández
Note - you can use multiple lines for the lineup; to continue the lineup
the line MUST end with ,;-, that is, comma (,), semicolon (;) or dash (-).
Examples:
Penalties: 1-0 Mario Gavranović, 1-1 Paul Pogba, 2-1 Fabian Schär, 2-2 Olivier Giroud,
3-2 Manuel Akanji, 3-3 Marcus Thuram, 4-3 Ruben Vargas,
4-4 Presnel Kimpembe, 5-4 Admir Mehmedi, Kylian Mbappé (save)
Penalty shootout: 0-0 Zinho (held), 0-1 Dudamel;
1-1 Júnior Baiano, 1-2 Gaviria;
2-2 Roque Júnior, 2-3 Yepes;
3-3 Rogério, 3-3 Bedoya (post);
4-3 Euller, 4-3 Zapata (wide)
Note - you can use multiple lines for the penalties; to continue the penalties
the line MUST end with ,;, that is, comma (,) or semicolon (;).
Examples:
Yellow Cards: Çağlar Söyüncü 88', Halil Dervişoğlu 90'
Yellow Cards: Nico Elvedi 32', Ricardo Rodríguez 62', Granit Xhaka 76', Manuel Akanji 108';
Raphaël Varane 30', Kingsley Coman 88', Benjamin Pavard 91'
Yellow cards: Sampaio 54', Argel 77'; Barros Schelotto 65', Bermúdez 76'
Red cards: Mosquera, Evair
Sent off: Páez
Examples:
Referee: Danny Makkelie (Netherlands)
Referee: Fernando Rapallini (Argentina)
Referee: Aquino (Paraguay)
ref: Jionni (Italy)
Examples:
Attendance: 44000
att: 23_000
Note - You CANNOT use commas in number e.g. 45,000 use underscore e.g. 45_000
Note - The focus for the Football.TXT format v1 is on English.
More formats with conventions used in German (Deutsch)
or Spanish (Español) are planned for later.
For example - conventions in German (Deutsch) incl.:
2:1 (0:1) instead of 2-1 (0-1)44. or (44.) instead of 44'Yes, you can. More than welcome. See Help & Support »