Trình cập nhật tệp ngôn ngữ Minecraft


11

Trong 1.13, các tệp ngôn ngữ Minecraft đã được chuyển từ dạng đa khóa đơn giản = định dạng giá trị sang JSON .

Thử thách

Viết chương trình chuyển đổi từ định dạng ban đầu trả về chuỗi JSON. Có thể lấy đầu vào bằng bất kỳ phương thức nhập chuẩn nào, đầu ra phải được json từ bất kỳ phương thức đầu ra tiêu chuẩn nào

Ví dụ, định dạng ban đầu chứa các dòng có cặp key = value

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

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

Nên được chuyển đổi thành một đối tượng JSON lớn có key = value

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

Một số chi tiết

  • Bất kỳ JSON hợp lệ nào cũng được phép miễn là nó chỉ chứa các cặp khóa / giá trị chính xác. Dấu phẩy được phép vì Minecraft cho phép chúng.
  • Những điều duy nhất phải được thoát là trích dẫn. (Không có dòng mới, dấu gạch chéo ngược hoặc những thứ phá vỡ json khác tồn tại trong tệp ngôn ngữ trước 1.13)
  • Các dòng trống nên được bỏ qua
  • Các dòng chứa chính xác một bằng

Các trường hợp thử nghiệm

Đầu vào:

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

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

Đầu ra:

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

Đầu vào:

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

Đầu ra:

{
  "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",
}

Đầu vào:

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

Đầu ra:

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

1
Làm thế nào để tile.dirt.nametrở thành "block.minecraft.dirt"?
Pavel

@Pavel uuh ... rất tiếc. Đã sửa lỗi đó. Đó là vô ý
pfg

5
Có đảm bảo rằng mỗi dòng không trống chứa chính xác 1 =?
dùng202729

@ user202729 có
pfg

3
Tôi sẵn sàng đặt cược rằng bạn thực sự cần một giải pháp cho vấn đề này và có ý định sử dụng một giải pháp để chuyển đổi các tập tin của bạn. :)
mbomb007

Câu trả lời:


4

Python 3, 91 77 byte

-14 byte nhờ OMᗺ

Tôi nghĩ rằng bản in của một từ điển Python sẽ đủ gần với JSON để biến nó thành một ngôn ngữ rất cạnh tranh cho thử thách này. Tuy nhiên, biểu diễn chuỗi của từ điển python đủ khác với JSON mà tôi đã may mắn hơn khi sử dụng thư viện JSON tích hợp của python. Tôi cá là điều này có thể được thực hiện ngắn gọn hơn trong JavaScript.

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

Hãy thử trực tuyến!


Biên tập:

Bash + Sed, 68 63 byte

Sửa lỗi nhờ OMᗺ và Đêm 2
-5 Byte nhờ OMᗺ

Tôi nhận ra rằng có thể hiệu quả hơn byte khi chuyển đổi trực tiếp văn bản thành JSON mà không cần gói nó trong một đối tượng, như cách tiếp cận của tôi đối với giải pháp python. Mỗi byte, sed là ngôn ngữ mạnh nhất để thay thế regex mà tôi biết.

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

Hãy thử trực tuyến!

Giải trình

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
Nếu bạn đang trả lời bằng hai ngôn ngữ khác nhau, vui lòng gửi dưới dạng hai câu trả lời riêng biệt.
mbomb007

Đối với câu trả lời bash + sed, hãy thử sử dụng -rcờ cho sed (+3 byte) để bạn không cần phải thoát khỏi các nhóm bắt (-4 byte) tio.run/##LYq7CgIxEEX7/ tựa
user41805

4

Vim, 44 byte

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

Giải trình:

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

3

Rust , 150 byte

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

Hãy thử trực tuyến!

Nó có dài hơn Java không?


2

Võng mạc 0.8.2 , 35 byte

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

Hãy thử trực tuyến! Sẽ là 34 byte trong Retina 1 khi bạn có thể sử dụng L$`.+thay vì G`..+. Giải trình:

"
\"

Thoát khỏi dấu ngoặc kép.

=
": "

Sửa lỗi phân tách khóa / giá trị. (Nếu giá trị có thể chứa a =, hãy sử dụng 1`=với chi phí là 2 byte.)

G`.

Xóa các dòng trống.

.+
    "$&",

Gói từng dòng trong dấu ngoặc kép. (Các trích dẫn bên trong đã được thêm vào trước đó.)

^
{¶
$
¶}

Bọc toàn bộ đầu ra trong {}s.


2

Husk , 22 byte

Thao tác chuỗi không thực sự là thế mạnh của Husk, nhưng nó đã làm khá tốt:

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

Hãy thử trực tuyến!

                      ¶  -- 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

Trớ trêu thay, có một thứ gọi là "Husk" trong Minecraft!
Chương trình Redwolf

2

Ruby , 56 byte

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

+6 byte cho -rjsoncờ phiên dịch.

Hãy thử trực tuyến!


1
@Piccolo bạn đã vượt qua cờ -rjson?
pfg

@pfg Wow, tôi thực sự đã làm rơi trái bóng đó haha. Tôi đã không chỉ quên sử dụng -rjson, mà còn giả định mà không thực sự kiểm tra rằng lỗi đó có phải là lỗi mà tôi đã gặp phải trước đó hay khôngto_h
Piccolo

2

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

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

Hãy thử trực tuyến!


Phiên bản 58 byte:

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

Hãy thử trực tuyến!


Cả hai phiên bản đều thêm dấu phẩy sau mỗi cặp khóa: value, về mặt kỹ thuật không tuân thủ JSON (dấu phẩy cuối cùng trước khi đóng }nên được bỏ qua và sẽ thất bại trong hầu hết các trình xác nhận JSON nghiêm ngặt). Đây là một bản ghi lại 58 byte nhanh chóng tạo ra hợp lệ (nếu xấu hơn cho người đọc con người) JSON: $c||='{';s'"'\"'g;/=/&&say qq|$c"$`":"$'"|;$c=','}{say'}' Tôi hy vọng bạn có thể tìm thấy một cái gì đó ngắn hơn / thanh lịch hơn một chút.
mousetrapper

@mousetrapper Đó là một cách hay để tránh BEGIN. OP rõ ràng cho phép dấu phẩy mặc dù: "Dấu phẩy được phép vì Minecraft cho phép chúng.". Hãy đăng bài đó như một câu trả lời mới, đề cập đến sự khác biệt.
- Phục hồi lại

Ah, vâng, điểm tốt, bỏ lỡ câu đó trong bài viết gốc. Việc gán mặc định chỉ có ý nghĩa nếu bạn đang cố gắng thay đổi ký tự đầu tiên, nếu không, bạn BEGINvẫn ngắn hơn trong trường hợp bạn chỉ muốn phát ra '{'. Tôi thích ENDkỹ thuật tránh né của bạn . Tôi biết rằng -nđã đặt một vòng lặp hiệu quả while(<>){} xung quanh mã của bạn; Tôi không biết nó đúng như thế nào.
mousetrapper

Tôi cũng khá ngạc nhiên khi lần đầu tiên phát hiện ra điều đó. Đây là một trong những tính năng Perl nằm giữa ranh giới giữa một vụ hack kỳ lạ và một cách tuyệt vời để thực hiện TIMTOWDI. Mặc dù vậy, tôi đã quên nó, vì vậy, tín dụng cho nó trong trường hợp này được chuyển đến Dennis trong chuỗi mẹo chơi gôn Perl 5 .
- Phục hồi Monica

2

Haskell , 75 71 byte

-4 byte nhờ Laikoni (sử dụng ký hiệu trên mức độ hiểu danh sách)!

Hoạt động với nhiều =trên một dòng:

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

Hãy thử trực tuyến!

Giải trình

Thuật ngữ span(/='=')<$>lines schia chuỗi trên đầu tiên =, để lại cho chúng tôi ("<initial part>","=<remaining line>"). Thực hiện khớp mẫu (a,_:b)đảm bảo rằng dòng không trống và đồng thời loại bỏ hàng đầu =.

Bây giờ chúng ta chỉ cần showcả hai ab(kèm theo nó trong dấu ngoặc kép và thoát dấu ngoặc kép), thực hiện một số định dạng ( :,ký tự) và cuối cùng gửi nó vào {}.


1
71 byte bằng cách sử dụng do: Hãy thử trực tuyến!
Laikoni

2

C (gcc) , 243 219 byte

Cảm ơn trần nhà cho lời đề nghị.

Tôi quyết định sử dụng một máy trạng thái để xử lý ba trường hợp (dòng mới, khóa, giá trị) và nó bật ra khá tốt. Ngoài ra, tôi đã đến ab sử dụng sự sụp đổ qua tính năng của switchvà các nhà điều hành stringizing vĩ mô!

Mặc dù thử thách không yêu cầu, tôi cũng đã thoát được \ký tự theo thông số JSON. Nếu ký tự đó sẽ không bao giờ có trong đầu vào, thì &&c-92có thể xóa thêm 5 byte nữa.

#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(});}

Hãy thử trực tuyến!


Đệ trình gốc: 243 byte

Đệ trình ban đầu giữ khoảng cách không cần thiết như trong các ví dụ JSON được cung cấp.

#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("}");}

Hãy thử trực tuyến!


2

JavaScript, 66 63 62 byte

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

-3 byte nhờ @redundancy

-1 byte nhờ @ l4m2




@ l4m2 Đối tượng RegExp được xâu chuỗi? Đã học được điều gì đó mới hôm nay
darrylyeo


1

Perl 6 , 48 byte

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

Ít hơn 2 byte nếu chúng ta có thể giả sử chính xác 1 dấu bằng trên một dòng không trống.

Hãy thử trực tuyến!

Ung dung:

{                   # 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

Nhân tiện, to-jsonthói quen bị phản đối, vì trình biên dịch sẽ cho bạn biết, nhưng ai quan tâm.



1

Ruby, 59 + 5 = 64

Nhu cầu -rjson(+5)

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

Giải trình:

->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",')}}`

Giả sử chỉ có một =trên mỗi dòng

Đoạn kiểm tra

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


Nên là 66 byte. \\ có thể đã được phân tích cú pháp dưới dạng \ khi đếm chiều dài.
dự phòng

1
@redundancy Tôi thực sự nên ngừng sử dụng "code".lengthtrong bảng điều khiển javascript để đếm thời lượng
Herman L

1

V , 30 byte

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

Mong đợi một đầu vào tại một thời điểm. Đoạn mã TIO chạy tất cả các trường hợp thử nghiệm đã cho dưới dạng một đầu vào.

Tôi mới biết về ánh xạ mở rộng của V, vì vậy các mẹo luôn được chào đón!

Hãy thử trực tuyến!

Giải trình

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 byte

#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(});}

Hãy thử trực tuyến!

Dựa trên triển khai của @ ErikF nhưng không có switch/case .

Phiên bản hơi vô căn cứ

#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 byte

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

Chạy như ống với -nRhoặc thử trực tuyến .

Chèn \strước $/mcho ngắt dòng Windows; \s*nếu ngắt dòng là không chắc chắn.
Chèn Usau $/mnếu giá trị chứa =.


1

Phi tiêu , 142 114 108 byte

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

Hãy thử trực tuyến!

  • -28 byte bằng cách loại bỏ hàm json.encode và sử dụng xây dựng chuỗi thông thường
  • -6 byte bằng cách xóa từ khóa 'mới' và một vài khoảng trắng
  • Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
    Licensed under cc by-sa 3.0 with attribution required.