.txt写入.json文件批处理或php文件需要

i need and search for a result to convert my .txt file to a .json file with that format:

{
"id":"12777475756802056",
"typ":"Solo",
"match":
    {
        "rank":"1",
        "playeruserid":"165496871657",
        "playername":"Example Name",
        "kills":"8",
        "points":"224000",
        "killer":"empty", // while firstplace
        "weapon":"empty" // while firstplace
    },
    {
        "rank":"2",
        "playeruserid":"654987654984",
        "playername":"Example Name 2",
        "kills":"4",
        "points":"168000",
        "killer":"Example Name",
        "weapon":"Shotgun"
    }
    ... another players here.
}

and my .txt file looks so, yep really bad... with so many spaces and all in one line...: https://pastebin.com/FP0C9BCj

i try this batch to remove the many spaces:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "sourcedir=D:\Users\Raphael\Desktop"
SET "destdir=D:\Users\Raphael\Desktop"
SET "filename1=%sourcedir%\matchreport.txt"
SET "outfile=%destdir%\outfile.txt"
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
 SET "line=%%a"
 SET "line=!line:?=!"
 SET "line=!line:/=-!"
 SET "line=!line::=!"
 SET "line=!line: =;!"
 ECHO !line!
)
)>"%outfile%"

GOTO :EOF

and idk now why can convert this now to a json file, while all informations on one line pro player, and the json format is now:

{"1. 5605****11014 Cl***ma  205000 + 19000 ( 8) = 224000"}

and sorry this is my first try to convert a txt to a json file have u any idea to convert this? :/

This almost works. (Requires PowerShell 3.0 or newer, so, Windows 8 or newer.) It's a Batch + PowerShell polyglot. Save it with a .bat extension.

<# : batch portion
@echo off & setlocal

set "file=test.txt"

powershell -noprofile "iex (${%~f0} | out-string)"
exit /b

: end batch / begin powershell #>

function Parse-Fields() {
    add-type -as Microsoft.VisualBasic
    $parser = new-object Microsoft.VisualBasic.FileIO.TextFieldParser($env:file)

    $parser.TextFieldType = "FixedWidth"
    $parser.TrimWhiteSpace = $true
    $parser.FieldWidths = @(7, 21, 25, 6, 9, 4, 12, 26, -1)

    while (!$parser.EndOfData) {
        try {
            $parser.ReadFields() -join "," -replace "[\(\+\)\.=]" | ?{ $_ -match "\d" }
        }
        catch {}
    }
    $parser.Close()
}

$header = "ID","GameUserId","Name","Rank","Kills","Score","Total","Killer","Weapon"
Parse-Fields | ConvertFrom-Csv -Header $header | ConvertTo-Json

Output:

[
    {
        "ID":  "1",
        "GameUserId":  "5605****11014",
        "Name":  "Cl***ma",
        "Rank":  "205000",
        "Kills":  "19000",
        "Score":  "8",
        "Total":  "224000",
        "Killer":  "",
        "Weapon":  "m4"
    },
    {
        "ID":  "2",
        "GameUserId":  "238444****020",
        "Name":  "Ap*******ift",
        "Rank":  "172403",
        "Kills":  "11550",
        "Score":  "3",
        "Total":  "183953",
        "Killer":  "Cl***ma",
        "Weapon":  "m4"
    },
    {
        "ID":  "3",
        "GameUserId":  "92******9515",
        "Name":  "Sw****UK",
        "Rank":  "156259",
        "Kills":  "14900",
        "Score":  "6",
        "Total":  "171159",
        "Killer":  "Ap*******ift",
        "Weapon":  "m4"
    },
    {
        "ID":  "4",
        "GameUserId":  "6583833***132",
        "Name":  "Moc********kap",
        "Rank":  "144805",
        "Kills":  "2000",
        "Score":  "1",
        "Total":  "146805",
        "Killer":  "Cl***ma",
        "Weapon":  "shotgun"
    },
    {
        "ID":  "5",
        "GameUserId":  "621***7360388",
        "Name":  "Ol***r***",
        "Rank":  "135920",
        "Kills":  "6200",
        "Score":  "3",
        "Total":  "142120",
        "Killer":  "Ap*******ift",
        "Weapon":  "m4"
    },
    {
        "ID":  "6",
        "GameUserId":  "189661****980",
        "Name":  "Op*********gon",
        "Rank":  "128661",
        "Kills":  "0",
        "Score":  "0",
        "Total":  "128661",
        "Killer":  "Sw****UK",
        "Weapon":  "m4"
    },
    {
        "ID":  "7",
        "GameUserId":  "6408****79452",
        "Name":  "M********nner",
        "Rank":  "122523",
        "Kills":  "3500",
        "Score":  "2",
        "Total":  "126023",
        "Killer":  "Sw****UK",
        "Weapon":  "shotgun"
    },
    {
        "ID":  "8",
        "GameUserId":  "59060***2163",
        "Name":  "A***g",
        "Rank":  "117207",
        "Kills":  "0",
        "Score":  "0",
        "Total":  "117207",
        "Killer":  "Ap*******ift",
        "Weapon":  "ak"
    },
    {
        "ID":  "9",
        "GameUserId":  "831467****599",
        "Name":  "*********ngstar",
        "Rank":  "112517",
        "Kills":  "0",
        "Score":  "0",
        "Total":  "112517",
        "Killer":  "Ol***r***",
        "Weapon":  "shotgun"
    },
    {
        "ID":  "10",
        "GameUserId":  "34542****7961",
        "Name":  "********Really",
        "Rank":  "108322",
        "Kills":  "5000",
        "Score":  "3",
        "Total":  "113322",
        "Killer":  "[Toxic Gas]",
        "Weapon":  null
    },
    {
        "ID":  "11",
        "GameUserId":  "904****58750",
        "Name":  "******tch",
        "Rank":  "104528",
        "Kills":  "3500",
        "Score":  "2",
        "Total":  "108028",
        "Killer":  "Sw****UK",
        "Weapon":  "shotgun"
    }
]

It probably won't take much to massage it to fit your requirements. I prefer objectifying data over scraping as flat text. The script first treats the data as a fixed-width CSV file. Once objectified as CSV data, it's the converted to JSON. If no one else suggests a better answer, maybe you can use this as a skeleton to build your project.


As an alternative, here's a Batch + JScript polyglot that's a bit more efficient than the PowerShell method, although it's longer. It doesn't suffer the overhead required by the TextFieldParser() class, and JScript is just faster than PowerShell in general. As a bonus, it should work with earlier versions of Windows, as long as IE version 9 or newer is installed (Vista SP2 I think?). If you're more comfortable with JavaScript, you might prefer this one.

@if (@CodeSection == @Batch) @then
@echo off & setlocal

set "file=test.txt"

cscript /nologo /e:JScript "%~f0" < "%file%"
exit /b

@end // end Batch / begin JScript

var stdin = WSH.CreateObject('Scripting.FileSystemObject').GetStandardStream(0),
    file = stdin.ReadAll(),
    htmlfile = WSH.CreateObject('htmlfile'),
    csvfields = {"ID": 7, "GameUserId": 21, "Name": 25, "Rank": 6, "Kills": 9,
        "Score": 4, "Total": 12, "Killer": 26, "Weapon": null};

String.prototype.clean = function() {
    var val = this.replace(/[\(\)\.\+=]/g, '').replace(/^\s+|\s+$/g, '');
    return /^\d+$/.test(val) ? val * 1 : val;
}

htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
var JSON = htmlfile.parentWindow.JSON,
    lines = obj = new htmlfile.parentWindow.Array();
htmlfile.close();

lines = file.split(/?
/g);
lines.splice(0,4);
for (var i=0; i<lines.length; i++) {
    for (var field in csvfields) {
        if (!obj[i]) obj.push({});
        obj[i][field] = csvfields[field] ?
            lines[i].substring(0, csvfields[field]).clean() : lines[i].clean();
        lines[i] = lines[i].substring(csvfields[field]);
    }
}

WSH.Echo(JSON.stringify(obj, null, '    '));

Output is similar, just with integer values unquoted.

Just for yucks, I implemented a regex solution using my JREPL.BAT utility.

I assume that the asterisks are an attempt to mask the data, and they don't appear in the actual input. I'm assuming the IDs are strictly numeric. I also assume that there are at least two spaces after each name (which serves to signal the end of the name).

Here is my batch script that uses JREPL.BAT:

@echo off
setlocal
::                      ID      Type
::         1            2       3
set "find1=^Match ID: *(\d+), *(.*?) *$"

::             Rank     ID     Name                     Kills     Points  Killer    Weapon
::         4   5        6      7                        8          9      10        11
set "find2=^ *(\d+)\. +(\d+) +(.*\S)  +\d+ \+ +\d+ \( *(\d+)\) = *(\d+) +(.*?\S)  +($|.*\S)"

set "repl1={
\qid\q:\q$2\q,
\qtyp\q:\q$3\q,
\qmatch\q:"

set "repl2=    {
"
set "repl2=%repl2%        \qrank\q:\q$5\q,
"
set "repl2=%repl2%        \qplayeruserid\q:\q$6\q,
"
set "repl2=%repl2%        \qplayername\q:\q$7\q,
"
set "repl2=%repl2%        \qkills\q:\q$8\q,
"
set "repl2=%repl2%        \qpoints\q:\q$9\q,
"
set "repl2=%repl2%        \qkiller\q:\q$10\q,
"
set "repl2=%repl2%        \qweapon\q:\q$11\q
"
set "repl2=%repl2%    },"

set "find=%find1%/%find2%"
set "repl=%repl1%/%repl2%"

jrepl find repl /v /t "/" /x /a /f test.txt | jrepl "," "
}" /x /inc -1

Here is pseudo-fixed "test.txt" input file with asterisks removed (digit or alpha substituted for asterisk). I intentionally added an inner space to some names and weapons just to test my regex.

Match ID: 6549999999997461, Solo
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Rank   GameUserId           Name                       Rank   Kills (##)    Total   Killer                    Weapon
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1.   5605999911014        Claaama                  205000 + 19000 ( 8) = 224000                             m4                              
  2.   2384449999020        Apaaaaaaaift             172403 + 11550 ( 3) = 183953   Claaama                   m4            
  3.   929999999515         Swaa aUK                 156259 + 14900 ( 6) = 171159   Apaaaaaaaift              m4            
  4.   6583833999132        Mocaaaaaaaakap           144805 +  2000 ( 1) = 146805   Claaama                   shotgun            
  5.   6219997360388        Olaaaraaa                135920 +  6200 ( 3) = 142120   Apaaaaaaaift              m4      
  6.   1896619999980        Opaaaaaaaaagon           128661 +     0 ( 0) = 128661   SwaaaaUK                  m4            
  7.   6408999979452        Maaaa aaanner            122523 +  3500 ( 2) = 126023   Swaa aUK                  shot gun              
  8.   590609992163         Aaaag                    117207 +     0 ( 0) = 117207   Apaaaaaaaift              ak      
  9.   8314679999599        aaaaaaaaangstar          112517 +     0 ( 0) = 112517   Olaaaraaa                 shotgun                  
 10.   3454299997961        aaaaaaaaReally           108322 +  5000 ( 3) = 113322   [Toxic Gas]                                              
 11.   9049999958750        aaaa atch                104528 +  3500 ( 2) = 108028   Swaa aUK                  shot gun

And here is the final result:

{
"id":"6549999999997461",
"typ":"Solo",
"match":
    {
        "rank":"1",
        "playeruserid":"5605999911014",
        "playername":"Claaama",
        "kills":"8",
        "points":"224000",
        "killer":"m4",
        "weapon":""
    },
    {
        "rank":"2",
        "playeruserid":"2384449999020",
        "playername":"Apaaaaaaaift",
        "kills":"3",
        "points":"183953",
        "killer":"Claaama",
        "weapon":"m4"
    },
    {
        "rank":"3",
        "playeruserid":"929999999515",
        "playername":"Swaa aUK",
        "kills":"6",
        "points":"171159",
        "killer":"Apaaaaaaaift",
        "weapon":"m4"
    },
    {
        "rank":"4",
        "playeruserid":"6583833999132",
        "playername":"Mocaaaaaaaakap",
        "kills":"1",
        "points":"146805",
        "killer":"Claaama",
        "weapon":"shotgun"
    },
    {
        "rank":"5",
        "playeruserid":"6219997360388",
        "playername":"Olaaaraaa",
        "kills":"3",
        "points":"142120",
        "killer":"Apaaaaaaaift",
        "weapon":"m4"
    },
    {
        "rank":"6",
        "playeruserid":"1896619999980",
        "playername":"Opaaaaaaaaagon",
        "kills":"0",
        "points":"128661",
        "killer":"SwaaaaUK",
        "weapon":"m4"
    },
    {
        "rank":"7",
        "playeruserid":"6408999979452",
        "playername":"Maaaa aaanner",
        "kills":"2",
        "points":"126023",
        "killer":"Swaa aUK",
        "weapon":"shot gun"
    },
    {
        "rank":"8",
        "playeruserid":"590609992163",
        "playername":"Aaaag",
        "kills":"0",
        "points":"117207",
        "killer":"Apaaaaaaaift",
        "weapon":"ak"
    },
    {
        "rank":"9",
        "playeruserid":"8314679999599",
        "playername":"aaaaaaaaangstar",
        "kills":"0",
        "points":"112517",
        "killer":"Olaaaraaa",
        "weapon":"shotgun"
    },
    {
        "rank":"10",
        "playeruserid":"3454299997961",
        "playername":"aaaaaaaaReally",
        "kills":"3",
        "points":"113322",
        "killer":"[Toxic Gas]",
        "weapon":""
    },
    {
        "rank":"11",
        "playeruserid":"9049999958750",
        "playername":"aaaa atch",
        "kills":"2",
        "points":"108028",
        "killer":"Swaa aUK",
        "weapon":"shot gun"
    }
}

Although primarily a html/xml/json data extraction tool, Xidel can also process raw text with a little XPath/XQuery magic.

I'm using dbenham's pseudo-fixed 'test.txt' as input

Match ID: 6549999999997461, Solo
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Rank   GameUserId           Name                       Rank   Kills (##)    Total   Killer                    Weapon
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  1.   5605999911014        Claaama                  205000 + 19000 ( 8) = 224000                             m4                              
  2.   2384449999020        Apaaaaaaaift             172403 + 11550 ( 3) = 183953   Claaama                   m4            
  3.   929999999515         Swaa aUK                 156259 + 14900 ( 6) = 171159   Apaaaaaaaift              m4            
  4.   6583833999132        Mocaaaaaaaakap           144805 +  2000 ( 1) = 146805   Claaama                   shotgun            
  5.   6219997360388        Olaaaraaa                135920 +  6200 ( 3) = 142120   Apaaaaaaaift              m4      
  6.   1896619999980        Opaaaaaaaaagon           128661 +     0 ( 0) = 128661   SwaaaaUK                  m4            
  7.   6408999979452        Maaaa aaanner            122523 +  3500 ( 2) = 126023   Swaa aUK                  shot gun              
  8.   590609992163         Aaaag                    117207 +     0 ( 0) = 117207   Apaaaaaaaift              ak      
  9.   8314679999599        aaaaaaaaangstar          112517 +     0 ( 0) = 112517   Olaaaraaa                 shotgun                  
 10.   3454299997961        aaaaaaaaReally           108322 +  5000 ( 3) = 113322   [Toxic Gas]                                              
 11.   9049999958750        aaaa atch                104528 +  3500 ( 2) = 108028   Swaa aUK                  shot gun
xidel.exe -s test.txt -e "let $line:=tokenize($raw,'
'),$match:=extract($line[1],'^Match ID: (\d+), (.+)',(1,2)) return {'id':$match[1],'type':$match[2],'match':$line[position()>4] ! (let $obj:=extract(.,'^ *(\d+)\. +(\d+) +(.*?\S) .+\( ?(\d+)\) = (\d+) {3}(.*?\S?.*?)?  +($|.*\S)',1 to 7) return {'rank':$obj[1],'playeruserid':$obj[2],'playername':$obj[3],'kills':$obj[4],'points':$obj[5],'killer':$obj[6],'weapon':$obj[7]})}"

or a bit more readable (prettyprinted):

xidel.exe -s test.txt -e ^" ^
  let $line:=tokenize( ^
        $raw, ^
        '
' ^
      ), ^
      $match:=extract( ^
        $line[1], ^
        'Match ID: (\d+), (.+)', ^
        (1,2) ^
      ) ^
  return { ^
    'id':$match[1], ^
    'type':$match[2], ^
    'match':$line[position()^>4] ! ( ^
      let $obj:=extract( ^
        ., ^
        '^^ *(\d+)\. +(\d+) +(.*?\S) .+\( ?(\d+)\) = (\d+) {3}(.*?\S?.*?)?  +($^|.*\S)', ^
        1 to 7 ^
      ) return { ^
        'rank':$obj[1], ^
        'playeruserid':$obj[2], ^
        'playername':$obj[3], ^
        'kills':$obj[4], ^
        'points':$obj[5], ^
        'killer':$obj[6], ^
        'weapon':$obj[7] ^
      } ^
    ) ^
  }^"

(the end of each line, as well as ",>,^,| needs to be escaped with a ^)

After opening 'test.txt' we first create 2 internal variables; $line and $match.
$line becomes a sequence of individual lines. $match becomes a sequence of the Match ID and the type by extracting this from the first line of the input.

After assigning these 2 internal variables we begin to create the json. The id attribute gets the Match ID is value, the type attribute 'Solo'.
Next we create the match array and start processing line 5 and up. Each line we feed to the extract()-function to create another internal variable (dbenham's regex slightly altered). This variable holds a sequence (7 items) of all the individual values we're looking for. And with this variable we finally populate the object, where we assign the rank attribute the first item, playeruserid attribute the second item, etc.

The output:

{
  "id": "6549999999997461",
  "type": "Solo",
  "match": [
    {
      "rank": "1",
      "playeruserid": "5605999911014",
      "playername": "Claaama",
      "kills": "8",
      "points": "224000",
      "killer": "",
      "weapon": "m4"
    },
    {
      "rank": "2",
      "playeruserid": "2384449999020",
      "playername": "Apaaaaaaaift",
      "kills": "3",
      "points": "183953",
      "killer": "Claaama",
      "weapon": "m4"
    },
    {
      "rank": "3",
      "playeruserid": "929999999515",
      "playername": "SwaaaaUK",
      "kills": "6",
      "points": "171159",
      "killer": "Apaaaaaaaift",
      "weapon": "m4"
    },
    {
      "rank": "4",
      "playeruserid": "6583833999132",
      "playername": "Mocaaaaaaaakap",
      "kills": "1",
      "points": "146805",
      "killer": "Claaama",
      "weapon": "shotgun"
    },
    {
      "rank": "5",
      "playeruserid": "6219997360388",
      "playername": "Olaaaraaa",
      "kills": "3",
      "points": "142120",
      "killer": "Apaaaaaaaift",
      "weapon": "m4"
    },
    {
      "rank": "6",
      "playeruserid": "1896619999980",
      "playername": "Opaaaaaaaaagon",
      "kills": "0",
      "points": "128661",
      "killer": "SwaaaaUK",
      "weapon": "m4"
    },
    {
      "rank": "7",
      "playeruserid": "6408999979452",
      "playername": "Maaaaaaaanner",
      "kills": "2",
      "points": "126023",
      "killer": "SwaaaaUK",
      "weapon": "shotgun"
    },
    {
      "rank": "8",
      "playeruserid": "590609992163",
      "playername": "Aaaag",
      "kills": "0",
      "points": "117207",
      "killer": "Apaaaaaaaift",
      "weapon": "ak"
    },
    {
      "rank": "9",
      "playeruserid": "8314679999599",
      "playername": "aaaaaaaaangstar",
      "kills": "0",
      "points": "112517",
      "killer": "Olaaaraaa",
      "weapon": "shotgun"
    },
    {
      "rank": "10",
      "playeruserid": "3454299997961",
      "playername": "aaaaaaaaReally",
      "kills": "3",
      "points": "113322",
      "killer": "[Toxic Gas]",
      "weapon": ""
    },
    {
      "rank": "11",
      "playeruserid": "9049999958750",
      "playername": "aaaaaatch",
      "kills": "2",
      "points": "108028",
      "killer": "SwaaaaUK",
      "weapon": "shotgun"
    }
  ]
}