Đây có phải là một tên biến hợp lệ?


23

Mục tiêu

Viết chương trình hoặc hàm kiểm tra xem tên biến có hợp lệ không và đầu ra 1 hoặc Truenếu nó hợp lệ, 0,5 nếu hợp lệ nhưng bắt đầu bằng dấu gạch dưới (_) và 0 hoặc Falsenếu nó không hợp lệ.

Quy tắc

  • Tên biến trong hầu hết các ngôn ngữ là hợp lệ nếu nó bắt đầu bằng dấu gạch dưới hoặc chữ cái (az, AZ, _) và phần còn lại của các ký tự là dấu gạch dưới, chữ cái hoặc số. (az, AZ, 0-9, _)
  • Đầu ra 1 hoặc Truenếu tên biến hợp lệ và 0 hoặc Falsenếu không hợp lệ.
  • Tuy nhiên, không nên thực hiện tốt khi bắt đầu một biến có dấu gạch dưới, vì vậy hãy trả về 0,5 nếu bắt đầu bằng dấu gạch dưới và tên hợp lệ.

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

Đầu vào

abcdefghijklmnop

Đầu ra

1

Đầu vào

_test_

Đầu ra

0.5 (bắt đầu bằng dấu gạch dưới)

Đầu vào

123abc

Đầu ra

0 (bắt đầu bằng một số)

Đầu vào

A_b1C_23

Đầu ra

1

Đầu vào

_!

Đầu ra

0 (không phải 0,5 vì nó không hợp lệ)

Đầu vào

magical pony1

Đầu ra

0 (không có khoảng trắng)

Tiêu chuẩn áp dụng.

Đây là , vì vậy mã ngắn nhất sẽ thắng.

Phần thưởng: -10% nếu chương trình / chức năng của bạn xuất ra 0một chuỗi trống ( "").


1
Chúng ta có thể xuất ra sự thật / giả / bất cứ điều gì không?
Máy

5
Chỉ cần lưu ý, trong python, dưới điểm số thường được sử dụng. Các lớp cần một hàm init , các hàm trợ giúp trong các lớp đôi khi được bắt đầu bằng dấu gạch dưới.
R

1
@EasterlyIrk hãy cẩn thận với đánh dấu nhỏ; ý bạn là vậy __init__; cũng có, không, lớp học không cần một __init__nhưng thường có một
con mèo

6
Chúng ta có thể cho rằng đầu vào sẽ không trống? (Hầu hết các câu trả lời hiện tại dường như không thành công cho đầu vào trống.)
Dennis

1
Phần thưởng đó có làm tròn lên hay xuống không? Nếu lên, nó thực sự không có giá trị cho bộ câu trả lời hiện tại
Blue

Câu trả lời:


13

JavaScript (ES6), 37 - 10% = 33,3 byte

Đã lưu 4 byte nhờ @ edc65

Đã lưu 5,6 byte nhờ @Mateon

s=>!/^\d|\W|^$/.test(s)/-~(s[0]=='_')

3
Bạn có chắc chắn điều này không phải là perl?
xem

8

05AB1E , 25 24 20 19 byte

Mã số:

¬D'_Qsa·+¹žj-""Q*2/

Giải trình:

¬                     # Push input and also push the first character.
 D                    # Duplicate the first character.
  '_Q                 # Check if it is equal to an underscore character.
     sa               # Swap and check the duplicate if it's an alphabetic character.
       ·              # Double the value.
        +             # Add both values up
         ¹            # Take the first input.
          žj-         # žj is short for [a-zA-Z0-9_]. This will be substracted from the
                        initial string. 
             ""Q      # Check if the string is empty.
                *     # Multiply this with the first value.
                 2/   # Halve it, resulting into 0.0, 0.5, or 1.0.

Nói tóm lại, công thức cho chuỗi strong mã giả là:

((s[0] == '_' + s.isalpha() × 2) × (s.remove([a-zA-Z0-9_]) == "")) / 2

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

Sử dụng mã hóa CP-1252 .


6

PHP (50 - 10% = 45)

Cảm ơn Schism cho -2 :)

preg_match('/^[a-z_]\w*$/i',$s)?$s[0]=='_'?.5:1:0;

Không phải để cạnh tranh với các câu trả lời golflang, nhưng tôi nghĩ rằng dù sao tôi cũng sẽ thử nó.

preg_match('/^[a-z_]\w*$/i', $s) # Matches every a-zA-Z0-9_ string that doesnt start with a number
?   $s[0] == '_'                   # Then, if it starts with an _
    ?   .5                         # give 0.5 points
    :   1                          # If it doesn't, give 1
:   0;                             # If it didn't match the regex, give 0

Một điều cần lưu ý là trong PHP, không có công cụ /usửa đổi, \wchỉ chọn các chữ cái ASCII. Trong một số ngôn ngữ / hương vị Regex khác, mẫu này sẽ không hoạt động.

Chỉnh sửa : Tôi thấy rất nhiều người sử dụng \ w và \ d trong câu trả lời của họ, khi họ sử dụng ngôn ngữ bao gồm các chữ cái và chữ số không phải ASCII. Đó không phải là câu đố. Họ sai. (Không thể downvote / bình luận nào, xin lỗi vì cần phải nói theo cách này.)


Chào mừng bạn đến với Câu đố lập trình và trao đổi mã Golf. Đây là một câu trả lời tuyệt vời; thường những thách thức về môn đánh gôn nằm trong các ngôn ngữ cũng như giữa chúng. Tôi sẽ cho bạn +1 cho giải pháp này! Làm tốt.
wizzwizz4

1
Bạn có thể cạo hai nhân vật với [a-z].../i.
Schism

@Schism Cảm ơn bạn. Không biết làm thế nào tôi có thể quên điều đó, thông thường tôi giỏi các loại câu đố regex này :)
Xesau

1
Về chỉnh sửa của bạn: bạn có thể cụ thể hơn - ngôn ngữ nào? Trong javascript \dhoàn toàn giống như [0-9]. \whoàn toàn giống với [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/
mẹo

Trang mã mà ngôn ngữ sử dụng là không liên quan; miễn là regex xử lý đúng ASCII, nó hợp lệ. Tất cả các câu trả lời dựa trên regex hiện tại đều hoạt động, theo hiểu biết của tôi. Bạn không cố gắng khớp tên biến trong ngôn ngữ của bạn; thay vào đó, bạn đang cố gắng khớp một tên biến dựa trên các quy tắc trong thử thách.
Mego

5

Võng mạc, 30 - 10% = 27 28 - 10% = 25,2 29 - 10% = 26,1 byte

Cả hai phiên bản đều đủ điều kiện nhận thưởng, vì chúng xử lý chính xác đầu vào trống (đầu ra 0)

Tôi đã phải sửa một lỗi gây ra bởi một trong các tính năng regex .NET, coi một số (đọc nhiều) ký tự Unicode là ký tự "từ". May mắn thay, điều này chỉ tốn một byte cho cả hai phiên bản. Nó chỉ đi vào việc thêm một công cụ sửa đổi để làm cho hành vi khớp regex tuân thủ các tiêu chuẩn ECMAScript. Thêm về điều đó ở đây .

Mới 28 phiên bản 29-byte, do @ MartinBüttner. Cảm ơn!

^ _
$ _¶_
Mẹ tôi ^ (?! \ D) \ w + $
2
0,5

Giải trình

Đầu tiên, chúng tôi kiểm tra xem đầu vào bắt đầu bằng dấu gạch dưới. Nếu có, đầu vào được nhân đôi, với một dòng mới ở giữa. Ví dụ: _test_-> _test_\n_test_, đâu \nlà dòng mới. Sau đó, chúng tôi cố gắng để phù hợp với bất cứ điều gì, mà không bắt đầu bằng một số, nhưng được theo sau bởi bất kỳ số lượng ký tự "từ" ( a-z, A-Z, chữ số và dấu gạch dưới) trên mỗi dòng . Lưu ý rằng nếu đầu vào bắt đầu bằng dấu gạch dưới và được thay thế thành hai dòng, điều này sẽ khớp với cả hai dòng. Sau đó, chúng tôi kiểm tra xem chúng tôi có 2 trận đấu không, và thay thế chúng bằng 0.5. Dòng trống hoặc không hợp lệ sẽ luôn mang lại 0 kết quả trùng khớp và các tên biến hợp lệ luôn mang lại 1 kết quả khớp.


Phiên bản 30 31 byte của riêng tôi

Ae` ^ \ d | \ W
^ _. *
0,5
^ \ D. *
1
^ $
0

Giải trình

Trước hết, chúng tôi kiểm tra nếu khởi đầu vào bằng một chữ số hoặc chứa một nhân vật phi-word (bất cứ điều gì khác hơn a-z, A-Z, chữ số và dấu gạch dưới). Nếu có, nó sẽ bị loại bỏ, vì nó không hợp lệ. Sau đó, chúng tôi kiểm tra nếu nó bắt đầu với một dấu gạch dưới. Nếu có, nó được thay thế bằng 0.5. Sau đó chúng tôi kiểm tra nếu nó bắt đầu với một nhân vật phi chữ số (vào thời điểm này các ký tự đầu tiên là một trong hai 0, a-zhoặc A-ZOnly. a-zA-Zđều là phòng không chữ số, rõ ràng). Nếu có, nó được thay thế bằng a 1. Sau đó, chúng tôi kiểm tra chuỗi trống và thay thế bằng 0.

Hãy thử trực tuyến!
Hãy thử trực tuyến! Phiên bản cũ


Đợi, đợi, đợi. Ở ^\D.*giai đoạn nó có thể bắt đầu bằng 0? Lạ nhỉ.
Máy

@CatsAreFluffy Nó có thể, nếu nó bắt đầu bằng một _và được thay thế bằng 0.5. Sau đó, nó bắt đầu bằng 0.
daavko

Điều này không chính xác cho 1 cho đầu vào Ψ.
admBorkBork

@TimmyD Thú vị. Tôi không hiểu tại sao nó làm như vậy. Kiểm tra nhanh chỉ ra rằng \wphù hợp với các ký tự không phải ASCII, điều này không nên làm (tôi đã cố gắng cung cấp cho nó ƜƝƞƟƠᎳᎴᎵᎶᎷᎸᎹlàm đầu vào). Tôi sẽ xem xét điều này sau. Giải pháp có thể dường như thay thế \wbằng [a-zA-Z\d_].
daavko

3

MATL , 27 byte

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Điều này hoạt động trong phiên bản hiện tại (15.0.0) của ngôn ngữ.

Đầu vào là một chuỗi với dấu ngoặc đơn.

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

Giải trình

1)      % take input implicitly. Get its first element
95=     % true if it equals 95 (underscore)
2/      % divide by 2: gives 0.5 if underscore, 0 if not
8M      % push first element of input again
3Y2     % predefined literal: string with all letters
m       % true if it's a letter
+       % add. Gives 1 if letter, 0.5 if underscore
G       % push input again
7M      % push string with all letters again
95h     % concatenate underscore
4Y2h    % predefined literal: string with all digits. Concatenate
mA      % true if all input chars belong to that concatenated string
*       % multiply. Display implicitly

3

Pyke , 21 byte

(không lọc, thêm chuỗi trừ, các hằng chuỗi khác nhau)

Qh~u{Q~J\_+-|!Qh\_qh/

Giải trình:

Qh~u{                 - Check first char isn't a digit
     Q~J\_+-          - Is the input alphanumeric + "_"
            |!        - Combine
              Qh\_q   - Is the first char an "_"
                   h/ - Combine

3

Python 3, 36 byte

lambda s:s.isidentifier()/-~(s[:1]=='_')

Mã này dài 40 byte và đủ điều kiện nhận thưởng -10% .

Lưu ý rằng điều này sẽ chỉ hoạt động chính xác cho các trang mã không có chữ cái / chữ số không phải ASCII.



2

Gogh , 29 byte

÷"[^\W\d]\w*"g¦"_.*"g+÷2=0.5¿

Chạy bằng cách sử dụng:

$ ./gogh no '÷"[^\W\d]\w*"g¦"_.*"g+÷2=0.5¿' "_test"

Giải trình

                   “ Implicit input                               ”
÷                  “ Duplicate the TOS                            ”
"[^\W\d]\w*"g      “ Fully match the STOS against the TOS (regex) ”
¦                  “ Swap the STOS and TOS                        ”
"_.*"g             “ Fully match the STOS against the TOS (regex) ”
+                  “ Add the TOS to the STOS                      ”
÷                  “ Duplicate the TOS                            ”
2=                 “ Determine if the TOS is equal to 2           ”
0.5¿               “ Leave the correct output on the stack        ”
                   “ Implicit output                              ”

2

Perl, 21 byte

$_=!/\W|^\d//2**/^_/

Điểm số bao gồm +1 byte cho -pchuyển đổi. Hãy thử nó trên Ideone .


bạn có thể có, nói -$_||$_=...để giải thích cho câu trả lời trống? (sử dụng -+là noop trong perl)
Ven

Không, đó là lỗi thời gian chạy. Nhưng ngay cả khi nó hoạt động, nó sẽ làm cho điểm của tôi tệ hơn.
Dennis

Tôi chỉ làm các bài kiểm tra tối giản, vì vậy tôi sẽ tin tưởng bạn. Công bằng rằng 10% của 21 byte không nhiều ..
Ven

2

Bình thường, 19 byte

c!:z"\W|^\d"0h!xz\_

Hãy thử nó với Trình biên dịch Pyth .

Lưu ý rằng điều này sẽ chỉ hoạt động chính xác cho các trang mã không có chữ cái / chữ số không phải ASCII.

Làm thế nào nó hoạt động

c!:z"\W|^\d"0h!xz\_  (implicit) Save the input in z.

  :z        0        Test if z matches the following regex:
    "\W|^\d"           A non-word character or a digit at the beginning.
                     This returns True iff z is an invalid name.
 !                   Apply logical NOT to yield True iff z is a valid name.
               xz\_  Find the first index of the underscore in z.
                     This yields 0 iff z begins with an underscore.
             h!      Apply logical NOT and increment.
                     This yields 2 if z begins with an underscore, 1 otherwise.
c                    Divide the two results.

2

Hệ số , 84 * 0,9 = 76,5

USE: regexp
[ R/ [_a-zA-Z]\w*/ R/ _.*/ [ matches? 1 0 ? ] bi-curry@ bi 0 = 1 2 ? / ]

Chạy trên trình nghe (thay thế), xác định một trích dẫn (hàm ẩn danh) lấy một chuỗi và xuất ra {0 | 1/2 | 1}.

Xác định nó là một từ, đó là 97 ký tự:

USE: regexp
: v ( s -- n ) R/ [_a-zA-Z]\w*/ R/ _.*/ [ matches? 1 0 ? ] bi-curry@ bi 0 = 1 2 ? / ;

Làm thế nào nó hoạt động:

R/ [_a-zA-Z]\w*/ R/ _.*/định nghĩa hai biểu thức chính quy. bi-curry@áp dụng một phần trích dẫn [ matches? 1 0 ? ]cho mỗi regex, để lại hai trích dẫn bị xáo trộn trên ngăn xếp.biáp dụng mỗi trích dẫn cho chuỗi đối số.

Mỗi trong số đó (trích dẫn bị nguyền rủa) để lại 1 hoặc 0, tùy thuộc vào việc chúng khớp. Các trận đấu đầu tiên trên các tên được hình thành tốt, lần thứ hai về các tên bắt đầu bằng dấu gạch dưới.

0 = 1 2 ? / Giá trị cuối cùng được thay thế bằng 1 nếu là 0 hoặc bằng 2 nếu là 1. Sau đó, giá trị đầu tiên (1 hoặc 0, hợp lệ hoặc không) được chia cho giá trị thứ hai (2 hoặc 1, bắt đầu bằng dấu gạch dưới hoặc không) .

Đây là loooong! Bất kỳ con trỏ để thu hẹp hơn một chút đánh giá cao ...

Và tôi ghét regexps!

Tái bút

{ 0 } [ "" v ] unit-test
{ 0 } [ "" v ] unit-test
{ 0 } [ "1" v ] unit-test
{ 0 } [ "1var" v ] unit-test
{ 0 } [ "var$" v ] unit-test
{ 0 } [ "foo var" v ] unit-test
{ 1 } [ "v" v ] unit-test
{ 1 } [ "var" v ] unit-test
{ 1 } [ "var_i_able" v ] unit-test
{ 1 } [ "v4r14bl3" v ] unit-test
{ 1/2 } [ "_" v ] unit-test
{ 1/2 } [ "_v" v ] unit-test
{ 1/2 } [ "_var" v ] unit-test
{ 1/2 } [ "_var_i_able" v ] unit-test
{ 1/2 } [ "_v4r14bl3" v ] unit-test

tất cả vượt qua bài kiểm tra;)


Chỉ cần tự hỏi, là khoảng trắng thực sự cần thiết? Tôi không thể nói chắc chắn vì tôi không biết ngôn ngữ hoặc có người phiên dịch.
Mama Fun Roll

@MamaFunRoll yeah, không phải ngôn ngữ chơi golf tốt nhất! Trong truyền thống Forth, chỉ có dấu phân cách là ký tự khoảng trắng.
fede s.

Ồ, tôi hiểu rồi. Ở đây, có một upvote.
Mama Fun Roll

Yay, ty! Bây giờ để phá vỡ sự bình luận của tôi - mọi nơi riêng tư!
fede s.

2

APL Dyalog , 19 byte - 10% = 17,1

{(0≤⎕NC⍵)÷1+'_'=⊃⍵}

{... ... }chức năng ẩn danh mà lập luận ngay được đại diện bởi
⊃⍵ký tự đầu tiên (mang đến cho không gian nếu trống)
'_'=1 nếu bằng 'thanh dưới, 0 nếu ngược lại
1+đánh giá đến 2 nếu thanh dưới ban đầu, 1 cách khác
⎕NC⍵ tên lớp ; -1 nếu tên không hợp lệ, 0 nếu không xác định (nhưng tên hợp lệ), 2-9 nếu được xác định (và do đó hợp lệ)


1

Toán học, 93 byte

If[#~StringMatchQ~RegularExpression@"[A-Za-z_][0-9A-Za-z_]*",If[#~StringTake~1=="_",.5,1],0]&

Tôi thực sự không chắc chắn nếu điều này có thể được chơi golf hơn nữa.


1

Perl, 34 + 1 = 35 byte

$_=/^([^\W\d])\w*$//(($1 eq"_")+1)

Sử dụng -pcờ.

Giải trình

$_=/^([^\W\d])\w*$//(($1 eq"_")+1)
   /^([^\W\d])\w*$/                 matches any string that starts with an underscore or a letter of the alphabet followed by 0 or more alphanumeric + underscore characters. The first character is stored in a capture group
                   /                divide result by
                    (($1 eq"_")+1)  (capture == "_") + 1. This is 1 if the first character was not an underscore and 2 if it was.
$_=                                 assign to $_ and implicitly print

[_a-zA-Z]-> [^\W\d]nếu perl hoạt động giống như JavaScript, tôi nghĩ bạn cũng phải làm\w*
Downgoat 19/03/2016

@Downgoat Có vẻ hoạt động tốt với \w+.
một spaghetto

khớp sai choa
Downgoat 19/03/2016

@Downgoat À, đúng rồi. Tôi hiểu rồi.
một spaghetto

1

Python, 84 -10% = 76 byte

lambda x:[0,[[.5,1][x[0]>'z'],0][x[0]<'A']][x.replace('_','a').isalnum()]if x else 0

0

JavaScript ES7, 37 byte

x=>!x.match(/\W|^\d/)/2**/^_/.test(x)

Dùng thử trực tuyến

Làm thế nào nó hoạt động:

x=>                                   // Fat arrow function
   !x.match(/\W|^\d/)                 // Gives false if contains non word or starting 
                                      //   with a digit. Booleans in numeric context will 
                                      //   be 0 or 1
                      2**             // 2 to the power of...
                         /^_/.test(x) // gives true if starting with '_'. 
                                      //   true -> 1 -> 2**1 -> 2
                                      //   false -> 0 -> 2**0 -> 1
                     /                // Devide the lValue boolean with the numeric rValue:
                                      // lValue = 0 or 1
                                      // rValue = 2 or 1

Câu trả lời của cảng @ Dennis's Perl


0

Ruby, 44 byte

->(s){s=~/^(_|\d)?\w*$/?$1?$1==?_?0.5:0:1:0}

Bạn không cần parens xung quanh các thông số cho lambdas stabby
Không phải là Charles

Ngoài ra nếu bạn có thể tìm ra một cách để loại bỏ phần ba đó, bạn có thể lưu một số byte. Có thể /^([a-z_]).../ithay vì/^(_|\d)?.../
Không phải là Charles

@NotthatCharles D'oh ... bạn nói đúng. Tôi sẽ cho nó một cái nhìn cận cảnh hơn khi tôi có cơ hội
Flambino

0

Ruby, 57 - 10% = 51,3 byte

->(s){case s
when'',/^\d/,/\W/
0
when/^_/
0.5
else
1
end}

Một cách tiếp cận khá ngây thơ


51,3 byte, nhớ bạn. :)
Xesau

@Xesau whoops - ngượng ngùng. Đã sửa ngay :)
Flambino

Bạn tiết kiệm được một lượng lớn byte nếu bạn sử dụng chuỗi ternary:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Ink Ink

@KevinLau Đúng - Tôi đã thêm một câu trả lời ruby trong tĩnh mạch đó rồi (mặc dù nó cũng không tuyệt lắm)
Flambino

0

Lua, 82 - 10% = 73,8

v=function(s)return(s:match("^[_%a]+[_%w]*$")and 1or 0)*(s:match("_")and.5or 1)end

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

print(v("a") == 1) -- true
print(v("1") == 0) -- true
print(v("_") == 0.5) -- true
print(v("") == 0) -- true
print(v("1a") == 0) -- true
print(v("a1") == 1) -- true
print(v("_1") == 0.5) -- true
print(v("_a") == 0.5) -- true
print(v("1_") == 0) -- true
print(v("a_") == 0.5) -- true

Tôi nghĩ bạn có thể sử dụng STDIN để ăn ít nhất 10 byte.
Rò rỉ Nun

0

Lua, 68 * .9 = 61,2 byte

s=arg[1]print(s:find("^[%a_][%w_]*$")and(s:find("^_")and.5or 1)or 0)

Đưa ra các đối số trên dòng lệnh

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.