Minecraft Language Files Updater


11

In 1.13 wurden Minecraft-Sprachdateien von einem einfachen mehrzeiligen Schlüssel = Wert-Format auf JSON umgestellt .

Herausforderung

Schreiben Sie ein Programm, das vom Originalformat konvertiert und eine JSON-Zeichenfolge zurückgibt. Die Eingabe kann mit jeder Standardeingabemethode erfolgen. Die Ausgabe muss mit einer beliebigen Standardausgabemethode erfolgen

Das Originalformat enthält beispielsweise Zeilen mit Schlüssel = Wert-Paaren

tile.dirt.name=Dirt
advMode.nearestPlayer=Use "@p" to target nearest player

build.tooHigh=Height limit for building is %s blocks

Sollte in ein großes JSON-Objekt mit key = value konvertiert werden

{
    "tile.dirt.name": "Dirt",
    "advMode.nearestPlayer": "Use \"@p\" to target nearest player",
    "build.tooHigh": "Height limit for building is %s blocks"
}

Ein paar Details

  • Jeder gültige JSON ist zulässig, solange er nur die richtigen Schlüssel / Wert-Paare enthält. Nachgestellte Kommas sind zulässig, da Minecraft dies zulässt.
  • Die einzigen Dinge, die entkommen müssen, sind Anführungszeichen. (Vor 1.13 waren in der Sprachdatei keine Zeilenumbrüche, Backslashes oder andere json-brechende Dinge vorhanden.)
  • Leere Zeilen sollten ignoriert werden
  • Zeilen enthalten genau eins gleich

Testfälle

Eingang:

tile.dirt.name=Dirt
advMode.nearestPlayer=Use "@p" to target nearest player

build.tooHigh=Height limit for building is %s blocks

Ausgabe:

{
    "tile.dirt.name": "Dirt",
    "advMode.nearestPlayer": "Use \"@p\" to target nearest player",
    "build.tooHigh": "Height limit for building is %s blocks"
}

Eingang:

translation.test.none=Hello, world!
translation.test.complex=Prefix, %s%2$s again %s and %1$s lastly %s and also %1$s again!
translation.test.escape=%%s %%%s %%%%s %%%%%s
translation.test.invalid=hi %
translation.test.invalid2=hi %  s
translation.test.args=%s %s
translation.test.world=world

Ausgabe:

{
  "translation.test.none": "Hello, world!",
  "translation.test.complex": "Prefix, %s%2$s again %s and %1$s lastly %s and also %1$s again!",
  "translation.test.escape": "%%s %%%s %%%%s %%%%%s",
  "translation.test.invalid": "hi %",
  "translation.test.invalid2": "hi %  s",
  "translation.test.args": "%s %s",
  "translation.test.world": "world",
}

Eingang:

stat.mineBlock=%1$s Mined
stat.craftItem=%1$s Crafted
stat.useItem=%1$s Used
stat.breakItem=%1$s Depleted

Ausgabe:

{
    "stat.mineBlock": "%1$s Mined",
    "stat.craftItem": "%1$s Crafted",
    "stat.useItem": "%1$s Used",
    "stat.breakItem": "%1$s Depleted"
}

1
Wie wird tile.dirt.namees "block.minecraft.dirt"?
Pavel

@ Pavel uuh ... whoops. Das wurde behoben. Das war unbeabsichtigt
pfg

5
Ist garantiert, dass jede nicht leere Zeile genau 1 enthält =?
user202729

@ user202729 ja
pfg

3
Ich würde wetten, dass Sie tatsächlich eine Lösung für dieses Problem benötigen und beabsichtigen, eine zum Konvertieren Ihrer Dateien zu verwenden. :)
mbomb007

Antworten:


4

Python 3, 91 77 Bytes

-14 Bytes dank OMᗺ

Ich dachte, dass der Ausdruck eines Python-Wörterbuchs nahe genug an JSON sein würde, um es zu einer sehr wettbewerbsfähigen Sprache für diese Herausforderung zu machen. Die Zeichenfolgendarstellung von Python-Wörterbüchern unterscheidet sich jedoch so stark von JSON, dass ich mit der in Python integrierten JSON-Bibliothek mehr Glück hatte. Ich wette, dies kann in JavaScript prägnanter durchgeführt werden.

import json
f=lambda x:json.dumps(dict(i.split("=")for i in x.split("\n")if i))

Probieren Sie es online aus!


Bearbeiten:

Bash + Sed, 68 63 Bytes

Fehlerbehebung dank OMᗺ und Night 2
-5 Bytes dank OMᗺ

Ich erkannte, dass es möglicherweise byteeffizienter ist, den Text direkt in JSON zu konvertieren, ohne ihn in einem Objekt zu bündeln, ebenso wie mein Ansatz für die Python-Lösung. Pro Byte ist sed die mächtigste Sprache für den Regex-Ersatz, die ich kenne.

echo {`echo "$1"|sed 's/"/\\\"/g;s/\(.*\)=\(.*\)/"\1":"\2",/'`}

Probieren Sie es online aus!

Erläuterung

echo {`                                  #  prints the leading curly brace
       echo "$1"|sed                     # feeds the input into sed
       's/"/\\"/g;                       # replaces " with \"
       s/\(.*\)=\(.*\)/"\1":"\2",/'      # surrounds the left and right hand sides of the equals with quotes and joins them with a colon
`}                                       # prints the closing curly brace

8
Wenn Sie in zwei verschiedenen Sprachen antworten, können Sie dies als zwei separate Antworten veröffentlichen.
mbomb007

Verwenden Sie für die Antwort bash + sed das -rFlag für sed (+3 Byte), damit Sie den Erfassungsgruppen (-4 Byte) nicht entkommen müssen. Tio.run/##LYq7CgIxEEX7/…
user41805

4

Vim, 44 Bytes

O{<Esc>:%s/"/\\"/g|%s/\v(.*)\=(.*)/"\1":"\2",
o}

Erläuterung:

O{<Esc>                                           Prepend {
       :%s/"/\\"/g                                Escape all "
                  |%s/\v(.*)\=(.*)/"\1":"\2",     Json-ify lines
o}                                                Append }

3

Rost , 150 Bytes

|s:String|s.replace('"',"\\\"").split('\n').filter(|l|l.len()>0).map(|l|format!("\"")+&l.replace('=',"\":\"")+"\",").fold(format!("{{"),|r,n|r+&n)+"}"

Probieren Sie es online aus!

Ist es länger als Java?


2

Retina 0,8,2 , 35 Bytes

"
\"
=
": "
G`.
.+
    "$&",
^
{¶
$
¶}

Probieren Sie es online aus! Wäre 34 Bytes in Retina 1, da Sie L$`.+anstelle von G`.und verwenden können .+. Erläuterung:

"
\"

Entkomme den Anführungszeichen.

=
": "

Korrigieren Sie das Schlüssel / Wert-Trennzeichen. (Wenn der Wert a enthalten könnte =, verwenden Sie ihn 1`=zu einem Preis von 2 Byte.)

G`.

Leere Zeilen entfernen.

.+
    "$&",

Schließen Sie jede Zeile in Anführungszeichen ein. (Die inneren Anführungszeichen wurden früher hinzugefügt.)

^
{¶
$
¶}

Wickeln Sie die gesamte Ausgabe in {}s.


2

Schale , 22 Bytes

Die Manipulation von Saiten ist nicht wirklich die Stärke von Husk, aber sie hat sich ziemlich gut bewährt:

`J"{}"J',mȯJ':msx'=fI¶

Probieren Sie es online aus!

                      ¶  -- split on newlines
                    fI   -- filter by identity (ie. remove empty strings)
         m(        )     -- with each line
                x'=      -- | split on '='
              ms         -- | show each (ie. enclose in quotes and escape quotes)
           J':           -- | join with ':'
      J',                -- join these with ','
`J"{}"                   -- join the string "{}" with the result

Ironischerweise gibt es in Minecraft etwas, das als "Schale" bezeichnet wird!
Redwolf Programme

2

Ruby , 56 Bytes

->x{x.split(?\n).map{|i|i.split(?=)}.to_h.to_json}

+6 Bytes für das -rjsonInterpreter-Flag.

Probieren Sie es online aus!


1
@ Piccolo hast du die -rjson Flagge passiert?
Pfg

@pfg Wow, ich habe den Ball wirklich fallen lassen haha. Ich hatte nicht nur vergessen zu verwenden -rjson, sondern auch angenommen, ohne tatsächlich zu überprüfen, dass der Fehler der gleiche war, den ich zuvor mitto_h
Piccolo

2

Perl 5 -nl -M5.010 , 58 54 Bytes

BEGIN{say'{'}s'"'\"'g;/=/&&say qq|"$`": "$'",|}{say'}'

Probieren Sie es online aus!


58-Byte-Version:

BEGIN{say'{'}s'"'\"'g;s/(.*)=(.*)/"$1": "$2",/;END{say'}'}

Probieren Sie es online aus!


Beide Versionen fügen nach jedem Schlüssel-Wert-Paar ein Komma hinzu, das technisch nicht mit JSON kompatibel ist (das letzte Komma vor dem Schließen }sollte weggelassen werden und schlägt bei den strengsten JSON-Validatoren fehl). Hier ist eine schnelle 58-Byte-Umschreibung, die ein gültiges (wenn auch für menschliche Leser hässlicheres) JSON ergibt: $c||='{';s'"'\"'g;/=/&&say qq|$c"$`":"$'"|;$c=','}{say'}' Ich gehe davon aus, dass Sie etwas finden können, das etwas kürzer / eleganter ist.
Mousetrapper

@mousetrapper Das ist ein guter Weg, um das zu vermeiden BEGIN. OP erlaubt jedoch explizit nachfolgende Kommas: "Nachgestellte Kommas sind zulässig, da Minecraft dies zulässt." Fühlen Sie sich frei, dies als neue Antwort zu posten und den Unterschied zu erwähnen.
Sundar - Reinstate Monica

Ah, ja, guter Punkt, ich habe diesen Satz im ursprünglichen Beitrag verpasst. Die Standardzuweisung ist nur sinnvoll, wenn Sie versuchen, das erste Zeichen zu variieren. Andernfalls ist Ihre Zuweisung BEGINnoch kürzer, wenn Sie nur das '{' ausgeben möchten. Ich mag deine ENDVermeidungstechnik. Ich wusste, dass dies -neine effektive while(<>){} Schleife um Ihren Code darstellt. Ich hatte keine Ahnung, wie wörtlich das war.
Mousetrapper

Ich war auch ziemlich überrascht, als ich das herausfand. Es ist eine dieser Perl-Funktionen, die die Grenze zwischen einem seltsamen Hack und einer brillanten Art, TIMTOWDI zu machen, überschreitet. Ich hatte es jedoch vergessen, daher geht dies in diesem Fall an Dennis im Thread mit den Perl 5-Golftipps .
Sundar - Reinstate Monica

2

Haskell , 75 71 Bytes

-4 Bytes dank Laikoni (mit Do-Notation über Listenverständnis)!

Funktioniert mit mehreren =in einer Zeile:

f s='{':do{(a,_:b)<-span(/='=')<$>lines s;show a++':':show b++","}++"}"

Probieren Sie es online aus!

Erläuterung

Der Begriff span(/='=')<$>lines steilt die Zeichenfolge auf der ersten =und lässt uns mit ("<initial part>","=<remaining line>"). Durch eine Musterübereinstimmung wird (a,_:b)sichergestellt, dass die Zeile nicht leer war, und gleichzeitig wird die führende Zeile entfernt =.

Jetzt müssen wir nur noch showbeides aund b(in Anführungszeichen einschließen und Anführungszeichen einschließen) einige Formatierungen ( :und ,Zeichen) vornehmen und es schließlich einschließen {}.



2

C (gcc) , 243 219 Bytes

Vielen Dank an Ceilingcat für den Vorschlag.

Ich entschied mich für eine Zustandsmaschine, um die drei Fälle (Zeilenumbruch, Schlüssel, Wert) zu behandeln, und es stellte sich als ziemlich gut heraus. Auch ich bekam ab verwenden , um den Durchfall Merkmal switchund die Makrozeichenfolge Operator!

Obwohl die Herausforderung dies nicht erforderte, bin ich dem \Charakter gemäß der JSON-Spezifikation entkommen . Wenn dieses Zeichen niemals in der Eingabe enthalten sein wird, &&c-92kann es für weitere 5 Bytes entfernt werden.

#define p(s)printf(#s,c)
#define a(i)case i:
c,s;f(){for(p({);(c=getchar())>0;)switch(s){a(0)if(c<11)break;s++,p(\42);a(1)c==61?s++,p(":"):p(%c);break;a(2)c-34&&c-92?c==10?p(\42\54),s=0:p(%c):p(\\%c);}s-2||p(\42);p(});}

Probieren Sie es online aus!


Ursprüngliche Einreichung: 243 Bytes

Die ursprüngliche Einreichung behielt unnötigen Abstand wie in den bereitgestellten JSON-Beispielen.

#define p(s)printf(s,c)
#define a(i)case i:
c,s;f(){for(p("{\n");(c=getchar())>0;)switch(s){a(0)if(c<11)break;s++,p("  \"");a(1)c==61?s++,p("\": \""):p("%c");break;a(2)c-34&&c-39?c==10?p("\",\n"),s=0:p("%c"):p("\\%c");}s==2&&p("\"\n");p("}");}

Probieren Sie es online aus!


2

JavaScript, 66 63 62 Bytes

s=>JSON.stringify(o=/(.+)=(.+)/g,s.replace(o,(_,a,b)=>o[a]=b))

-3 Bytes dank @redundancy

-1 Byte dank @ l4m2




@ l4m2 Stringified RegExp-Objekte? Habe heute etwas Neues gelernt 🤯
darrylyeo


1

Perl 6 , 48 Bytes

{to-json %(.lines.grep(?*)>>.split("=",2).flat)}

2 Bytes weniger, wenn wir in einer nicht leeren Zeile genau 1 Gleichheitszeichen annehmen können.

Probieren Sie es online aus!

Ungolfed:

{                   # An anonymous block, taking 1 string which ends in $_.
    to-json         # Convert a Perl 6 number, string, list or hash to JSON and return it.
    %(              # Force to hash (dictionary)
        .lines      # Break $_ (implicitly assumed) into a list of lines.
        .grep(?*)   # Pick only those that are True (non-empty).
        >>.         # For each element in the list, call the following method ... 
        split("=",2) # ... split the string at =, making at most 2 chunks.
        .flat       # That gives a list of 2-element lists. Flatten it.
    )               # List is converted into the hash like this: { first element => second element, third => fourth, ... }
}                   # Implicitly return

Übrigens ist die to-jsonRoutine veraltet, wie der Compiler Ihnen sagen wird, aber wen interessiert das?



1

Ruby, 59 + 5 = 64

Bedürfnisse -rjson(+5)

->c{Hash[*c.split(?\n).map{|l|l.split ?=}.flatten].to_json}

Erläuterung:

->c{                                                      } # anonymous function with param c
    Hash[*                                       ]          # converts ["a", "b", "c", "d"] into {"a": "b", "c": "d"}
          c.split(?\n)                                      # splits c into lines
                      .map{|l|          }                   # map lines so each element represents
                              l.split ?=                    # an array of itself but split by =
                                         .flatten           # merges 2d array to 1d (also gets rid of empty elements for newlines
                                                  .to_json  # converts hash to json

1

JavaScript (ES6), 66 Byte

s=>`{${s.replace(/"/g,'\\"').replace(/(.*)=(.*)/g,'"$1":"$2",')}}`

Angenommen, es gibt nur eine =pro Zeile

Snippet testen

f=s=>`{${s.replace(/"/g,'\\"').replace(/(.*)=(.*)/g,'"$1":"$2",')}}`
<textarea id="i" onkeyup="o.innerText=f(i.value)"></textarea><pre id="o">


Sollte 66 Bytes sein. \\ wurde beim Zählen der Länge möglicherweise als \ analysiert.
Redundanz

1
@redundancy Ich sollte wirklich aufhören, "code".lengthin der Javascript-Konsole zu verwenden, um die Länge zu zählen
Herman L

1

V , 30 Bytes

O{␛Í"/\\"
ggòeÉ"vyf=Plp$pa,òo}

Erwartet jeweils eine Eingabe. Das TIO-Snippet führt alle angegebenen Testfälle als eine einzige Eingabe aus.

Ich bin neu in den erweiterten Zuordnungen von V, daher sind Tipps immer willkommen!

Probieren Sie es online aus!

Erläuterung

O{␛                  # insert { on a new line above
   Í                 # global substitution across all lines
    "/\\"            #   " => \"
gg                   # go to first line
  ò                  # recursively...
   e                 #   forward to end of word; if at end of line, applies to next word below
    É"               #   prepend " to first non-whitespace char
      vy             #   copy current character (i.e. ")
        f=Plp        #   paste " before and after the next =
             $pa,    #   paste " at end of line and append ,
                 ò   # ...end
                  o} # insert } on a new line below

1

C (gcc) , 172 Bytes

#define p(s)printf(#s,c)
c,s;f(){for(p({);~(c=getchar());)s-2?c>10|s&&(s||(s+=p(\42)),c==61?s++,p(":"):p(%c)):c-34&&c-92?c==10?s=!p(\42\54):p(%c):p(\\%c);s-2||p(\42);p(});}

Probieren Sie es online aus!

Basierend auf der Implementierung von @ ErikF, jedoch ohne switch/case.

Leicht ungolfed Version

#define p(s)printf(#s,c)
c,s;
f(){
 for(p({);~(c=getchar());)
  s-2?
   c>10|s&&(
    s||
     (s+=p(\42)),
    c==61?
     s++,
     p(":")
    :
     p(%c)
   )
  :
   c-34&&c-92?
    c==10?
     s=!p(\42\54)
    :
     p(%c)
   :
    p(\\%c);
 s-2||p(\42);
 p(});
}



1

PHP, 87 Bytes

preg_match_all("/^(.*)=(.*)$/m",$argn,$m);echo json_encode(array_combine($m[1],$m[2]));

Laufen Sie als Pipe mit -nRoder probieren Sie es online aus .

\sVorher einfügen $/mfür Windows-Zeilenumbrüche; \s*wenn Zeilenumbrüche ungewiss sind. Nach
einfügen, wenn Werte enthalten .U$/m=


1

Dart , 142 114 108 Bytes

f(s)=>"""{${s.replaceAll('"','\\"').replaceAllMapped(RegExp(r'(.*)=(.*)'),(m)=>'"${m[1]}":"${m[2]}",')}}""";

Probieren Sie es online aus!

  • -28 Bytes durch Entfernen der Funktion json.encode und Verwenden der regulären Zeichenfolgenerstellung
  • -6 Bytes durch Entfernen des Schlüsselworts 'new' und einiger Leerzeichen
  • Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
    Licensed under cc by-sa 3.0 with attribution required.