Skip to content

Instantly share code, notes, and snippets.

@AlienHoboken
Last active October 14, 2021 15:31
Show Gist options
  • Save AlienHoboken/5571903 to your computer and use it in GitHub Desktop.
Save AlienHoboken/5571903 to your computer and use it in GitHub Desktop.
This short PHP script will create valid JSON data from Valve Data Format (VDF) data, such as items_game.txt files for TF2 and DotA 2. This allows for much greater ease in parsing the data it contains.
<?php
//load VDF data either from API call or fetching from file/url
//no matter your method, $json must contain the VDF data to be parsed
$json = file_get_contents("items_game.txt");
//encapsulate in braces
$json = "{\n$json\n}";
//replace open braces
$pattern = '/"([^"]*)"(\s*){/';
$replace = '"${1}": {';
$json = preg_replace($pattern, $replace, $json);
//replace values
$pattern = '/"([^"]*)"\s*"([^"]*)"/';
$replace = '"${1}": "${2}",';
$json = preg_replace($pattern, $replace, $json);
//remove trailing commas
$pattern = '/,(\s*[}\]])/';
$replace = '${1}';
$json = preg_replace($pattern, $replace, $json);
//add commas
$pattern = '/([}\]])(\s*)("[^"]*":\s*)?([{\[])/';
$replace = '${1},${2}${3}${4}';
$json = preg_replace($pattern, $replace, $json);
//object as value
$pattern = '/}(\s*"[^"]*":)/';
$replace = '},${1}';
$json = preg_replace($pattern, $replace, $json);
//we now have valid json which we can use and/or store it for later use
file_put_contents("items_game.json", $json);
/* NB: this does not allow for creation of json arrays, however.
* if you wish to keep working with the json data in PHP, you could
* do something like this to get an array where needed. eg. for items
*/
$data->items_game->items = get_object_vars($data->items_game->items); //items object is now an array
?>
@fnsoxt
Copy link

fnsoxt commented Aug 10, 2014

i love it, thanks a million

@sbmsr
Copy link

sbmsr commented Aug 12, 2014

beautiful stuff - thank you so much.

@jesobuild
Copy link

Very nice, but it can't deal with " as it actually interprets them as new values. I'm not good with regex at all though, otherwise I would change it myself. :)

@Tinario
Copy link

Tinario commented Feb 14, 2017

The code causes some errors :(

@AlienHoboken
Copy link
Author

@Tinario What errors? This is pretty old stuff now.

@itsmh
Copy link

itsmh commented Oct 10, 2017

Works neat but i just found out a problem some league names contain the \" character to escape double quotes like
"name" "Lima Five Peru Season \"Killer\"" which causes corrupted json output

			"name": "Lima Five Peru Season \",Killer\"": "prefab",		"league": "creation_date",		"2015-08-17": "image_banner",		"econ/leagues/subscriptions_lima_five_per__sesin__killer__ingame": "image_inventory",		"econ/leagues/subscriptions_lima_five_per__sesin__killer_": "item_description",		"#DOTA_Item_Desc_Lima_Five_Peru_Season_Killer": "item_name",		"#DOTA_Item_Lima_Five_Peru_Season_Killer": "item_type_name",		"#DOTA_WearableType_Ticket": "price_info",: {
				"category_tags": "Tournaments",
				"date": "8/17/2015",
				"price": "99"
			},
			"tool": {
				"type": "league_view_pass",
				"use_string": "#ConsumeItem",
				"usage": {
					"league_id": "3572",
					"order": "2662",
					"tier": "amateur",
					"location": "southamerica"
				}
			},
			"tournament_url": "http://www.limafiveperu.com",
			"used_by_heroes": "1"
		}

by editing the replace values pattern part i've fixed this
$pattern = '/"([^"]*)"\s*"([^"](.*|\\"))"/';

		"16348": {
			"name": "Lima Five Peru Season \"Killer\"",
			"prefab": "league",
			"creation_date": "2015-08-17",
			"image_banner": "econ/leagues/subscriptions_lima_five_per__sesin__killer__ingame",
			"image_inventory": "econ/leagues/subscriptions_lima_five_per__sesin__killer_",
			"item_description": "#DOTA_Item_Desc_Lima_Five_Peru_Season_Killer",
			"item_name": "#DOTA_Item_Lima_Five_Peru_Season_Killer",
			"item_type_name": "#DOTA_WearableType_Ticket",
			"price_info": {
				"category_tags": "Tournaments",
				"date": "8/17/2015",
				"price": "99"
			},
			"tool": {
				"type": "league_view_pass",
				"use_string": "#ConsumeItem",
				"usage": {
					"league_id": "3572",
					"order": "2662",
					"tier": "amateur",
					"location": "southamerica"
				}
			},
			"tournament_url": "http://www.limafiveperu.com",
			"used_by_heroes": "1"
		}
}

hope helps.

thanks in advance

@krll-kov
Copy link

krll-kov commented Sep 10, 2021

"Killer"

But this replacement creates a problem with values which contain \n
image

So it's better to replace encapsulated quotes with normal ones(or remove them at all) and leave the previous expression

"(.+?)"\t*"([\S\s]*?)"\s (the best for now)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment