Ist das ein gültiger Variablenname?

23

Zielsetzung

Schreiben Sie ein Programm oder eine Funktion, die prüft, ob ein Variablenname gültig ist und 1 ausgibt oder Trueob er gültig ist, 0,5, wenn er gültig ist, aber mit einem Unterstrich (_) beginnt, und 0, oder Falsewenn er ungültig ist.

Regeln

  • Ein Variablenname ist in den meisten Sprachen gültig, wenn er mit einem Unterstrich oder Buchstaben (az, AZ, _) beginnt und die restlichen Zeichen entweder Unterstriche, Buchstaben oder Zahlen sind. (az, AZ, 0-9, _)
  • Ausgang 1 oder Truewenn der Variablenname gültig ist und 0 oder Falsewenn nicht gültig.
  • Es ist jedoch nicht ratsam, eine Variable mit einem Unterstrich zu beginnen. Geben Sie also 0,5 zurück, wenn sie mit einem Unterstrich beginnt und der Name gültig ist.

Testfälle

Eingang

abcdefghijklmnop

Ausgabe

1

Eingang

_test_

Ausgabe

0.5 (beginnt mit einem Unterstrich)

Eingang

123abc

Ausgabe

0 (beginnt mit einer Zahl)

Eingang

A_b1C_23

Ausgabe

1

Eingang

_!

Ausgabe

0 (nicht 0,5, weil es nicht gültig ist)

Eingang

magical pony1

Ausgabe

0 (kein Platz)

Es gelten Standardlücken .

Das ist , also gewinnt der kürzeste Code.

Bonus: -10%, wenn Ihr Programm / Ihre Funktion 0eine leere Zeichenfolge ausgibt ( "").

Muschelpulver314
quelle
1
Können wir wahrheitsgemäß / falsch / irgendetwas ausgeben?
CalculatorFeline
5
In Python werden oft Under Scores verwendet. Klassen benötigen eine Init- Funktion, Hilfsfunktionen in Klassen werden manchmal mit einem Unterstrich begonnen.
Rɪᴋᴇʀ
1
@EasterlyIrk Vorsicht vor Mini-Markdown; du meintest __init__; auch, nein, Klassen nicht brauchen eine __init__aber in der Regel eine haben
Katze
6
Können wir davon ausgehen, dass die Eingabe nicht leer sein wird? (Die meisten aktuellen Antworten scheitern anscheinend bei leerer Eingabe.)
Dennis,
1
Rundet dieser Bonus auf oder ab? Wenn auf, lohnt es sich wirklich nicht für die aktuelle Reihe von Antworten
Blue

Antworten:

13

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

4 Bytes gespart dank @ edc65

5,6 Bytes dank @Mateon eingespart

s=>!/^\d|\W|^$/.test(s)/-~(s[0]=='_')
Downgoat
quelle
3
Bist du dir absolut sicher, dass dies nicht Perl ist?
Siehe auch
8

05AB1E , 25 24 20 19 Bytes

Code:

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

Erläuterung:

¬                     # 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.

Kurz gesagt slautet die Formel für die Zeichenfolge im Pseudocode:

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

Probieren Sie es online!

Verwendet CP-1252- Codierung.

Adnan
quelle
6

PHP (50 - 10% = 45)

Danke an Schism für den -2 :)

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

Ich wollte nicht mit den Golflang-Antworten mithalten, aber ich dachte, ich würde es trotzdem versuchen.

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

Zu beachten ist, dass in PHP ohne den /uModifikator \wnur ASCII-Buchstaben ausgewählt werden. In einigen anderen Sprachen / Regex-Varianten funktioniert dieses Muster nicht.

Bearbeiten : Ich sehe viele Leute, die in ihren Antworten \ w und \ d verwenden, wenn sie eine Sprache verwenden, die auch Nicht-ASCII-Buchstaben und -Ziffern enthält. Das ist NICHT das Rätsel. Sie liegen falsch. (Ich kann noch nicht abstimmen / kommentieren, es tut mir leid, dass ich das so sagen muss.)

Xesau
quelle
Willkommen beim Programmieren von Rätseln und beim Code Golf Stack Exchange. Dies ist eine großartige Antwort. Oft sind Code-Golf- Herausforderungen sowohl innerhalb als auch zwischen den Sprachen. Ich gebe dir +1 für diese Lösung! Gut gemacht.
wizzwizz4
1
Mit können Sie zwei Zeichen abschneiden [a-z].../i.
Schism
@Schism Danke. Ich weiß nicht, wie ich es geschafft habe, das zu vergessen. Normalerweise bin ich gut in solchen Regex-Rätseln :)
Xesau
1
Zu Ihrer Bearbeitung: Können Sie präziser sein - welche Sprachen? In Javascript \dist genau das gleiche wie [0-9]. \wist genau das gleiche wie [A-Za-z0-9_] developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/…
edc65
Die von der Sprache verwendete Codepage ist irrelevant. Solange der reguläre Ausdruck ASCII korrekt verarbeitet, ist er gültig. Meines Wissens nach funktionieren alle aktuellen auf Regex basierenden Antworten. Sie versuchen nicht, einen Variablennamen in Ihrer Sprache zu finden. Sie versuchen vielmehr, einen Variablennamen anhand der Regeln in der Challenge zu ermitteln.
Mego
5

Retina, 30 - 10% = 27 28 - 10% = 25,2 29 - 10% = 26,1 Bytes

Beide Versionen sind für den Bonus qualifiziert, da sie leere Eingaben korrekt handhaben (Ausgaben 0)

Ich musste einen Fehler beheben, der durch eine der .NET-Regex-Funktionen verursacht wurde, bei denen einige (so viele) Unicode-Zeichen als "Wort" -Zeichen betrachtet werden. Zum Glück hat mich das in beiden Versionen nur ein einziges Byte gekostet. Es musste nur ein Modifikator hinzugefügt werden, um das Regex-Übereinstimmungsverhalten mit den ECMAScript-Standards in Einklang zu bringen. Mehr dazu hier .

Neue 28 29-Byte-Version von @ MartinBüttner. Vielen Dank!

^ _
$ _¶_
Mme` ^ (?! \ D) \ w + $
2
0,5

Erläuterung

Zuerst prüfen wir, ob die Eingabe mit einem Unterstrich beginnt. In diesem Fall wird die Eingabe mit einem Zeilenumbruch dupliziert. Zum Beispiel: _test_-> _test_\n_test_, wo \nist der Zeilenumbruch. Dann versuchen wir , alles zu passen, die nicht mit einer Zahl beginnt, wird aber von einer beliebigen Anzahl von „Wort“ Zeichen (gefolgt a-z, A-Z, Ziffern und Unterstrich) in jeder Zeile . Beachten Sie, dass, wenn die Eingabe mit einem Unterstrich begann und durch zwei Zeilen ersetzt wurde, beide Zeilen übereinstimmen. Dann überprüfen wir, ob wir 2 Übereinstimmungen hatten, und ersetzen sie durch 0.5. Leere oder ungültige Zeilen ergeben immer 0 Übereinstimmungen und gültige Variablennamen ergeben immer 1 Übereinstimmung.


Meine eigene 30 31-Byte-Version

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

Erläuterung

Zunächst einmal überprüfen wir , ob Eingabe beginnt mit einer Ziffer oder ein Nicht-Wortzeichen enthält (etwas anderes als a-z, A-Z, Ziffern und Unterstrich). Wenn dies der Fall ist, wird es verworfen, da es ungültig ist. Dann prüfen wir, ob es mit einem Unterstrich beginnt. Wenn ja, wird es durch ersetzt 0.5. Dann überprüfen wir , ob es mit einem nicht-stelligen Zeichen beginnt (an dieser Stelle das erste Zeichen ist entweder 0, a-zoder A-Z. Nur a-zund A-Zsind nicht-Ziffern, natürlich). Wenn dies der Fall ist, wird es durch ein ersetzt 1. Dann suchen wir nach einer leeren Zeichenkette und ersetzen sie durch 0.

Probieren Sie es online!
Probieren Sie es online! Alte Version

Daavko
quelle
Warte warte warte. Auf der ^\D.*Bühne kann es mit einer 0 beginnen? Das ist komisch.
CalculatorFeline
@CatsAreFluffy Kann es, wenn es mit a angefangen hat _und durch ersetzt wurde 0.5. Dann geht es
los
Dies gibt fälschlicherweise eine 1 für die Eingabe Ψ.
AdmBorkBork
@TimmyD Interessant. Ich verstehe nicht, warum das so ist. Schnelle Überprüfung zeigt an, dass \wNicht-ASCII-Zeichen übereinstimmen, was nicht möglich ist (ich habe versucht, es ƜƝƞƟƠund ᎳᎴᎵᎶᎷᎸᎹals Eingabe zu geben ). Ich werde das später untersuchen. Mögliche Lösung scheint zu ersetzen \wmit [a-zA-Z\d_].
Daavko
3

MATL , 27 Bytes

1)95=2/8M3Y2m+G7M95h4Y2hmA*

Dies funktioniert in der aktuellen Version (15.0.0) der Sprache.

Die Eingabe ist eine Zeichenfolge mit einfachen Anführungszeichen.

Probieren Sie es online!

Erläuterung

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
Luis Mendo
quelle
3

Pyke , 21 Bytes

(Nicht konkurrierende, hinzugefügte String-Subtraktion, verschiedene String-Konstanten)

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

Erläuterung:

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
Blau
quelle
3

Python 3, 36 Bytes

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

Der Code ist 40 Byte lang und qualifiziert sich für den Bonus von -10% .

Beachten Sie, dass dies nur für Codepages korrekt funktioniert, die keine Nicht-ASCII-Buchstaben / Ziffern enthalten.

Dennis
quelle
2

Pyth, 27 Bytes

c!|-rz0++G\_JjkUT}hzJhqhz\_

Test Suite

Blau
quelle
2

Gogh , 29 Bytes

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

Ausführen mit:

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

Erläuterung

                   “ 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                              ”
Zach Gates
quelle
2

Perl, 21 Bytes

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

Die Punktzahl enthält +1 Byte für den -pSwitch. Probieren Sie es auf Ideone .

Dennis
quelle
könnten Sie sagen -$_||$_=..., um die leere Antwort zu erklären? (mit -weil +ist ein Noop in Perl)
Ven
Nein, das ist ein Laufzeitfehler. Aber selbst wenn es funktionieren würde, würde es meine Punktzahl verschlechtern.
Dennis
Ich habe nur minimalistische Tests gemacht, also vertraue ich dir. Ziemlich gut , dass 10% von 21 Bytes ist nicht viel ..
Ven
2

Pyth, 19 Bytes

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

Probieren Sie es mit dem Pyth-Compiler .

Beachten Sie, dass dies nur für Codepages korrekt funktioniert, die keine Nicht-ASCII-Buchstaben / Ziffern enthalten.

Wie es funktioniert

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.
Dennis
quelle
2

Faktor 84 * 0,9 = 76,5

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

Läuft auf dem Listener (repl), definiert ein Zitat (anonyme Funktion), das eine Zeichenfolge annimmt und {0 | ausgibt 1/2 | 1}.

Wenn man es als ein Wort definiert, sind es 97 Zeichen:

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

Wie funktioniert es:

R/ [_a-zA-Z]\w*/ R/ _.*/definiert zwei reguläre Ausdrücke. bi-curry@Wendet das Zitat teilweise [ matches? 1 0 ? ]auf jeden Regex an und belässt zwei Curry-Zitate auf dem Stapel.biWendet jedes Zitat auf die Argumentzeichenfolge an.

Jedes dieser (Curry-Zitate) hinterlässt entweder eine 1 oder eine 0, je nachdem, ob sie übereinstimmen. Der erste stimmt mit den wohlgeformten Namen überein, der zweite mit den Namen, die mit einem Unterstrich beginnen.

0 = 1 2 ? / Der letzte Wert wird durch eine 1 ersetzt, wenn er 0 war, oder durch eine 2, wenn er 1 war. Dann wird der erste (1 oder 0, gültig oder nicht) durch den zweiten geteilt (2 oder 1, beginnt mit einem Unterstrich oder nicht) .

Das ist langweilig! Alle Hinweise auf ein bisschen mehr geschätzt schrumpfen ...

Und ich hasse Regexps!

PS.

{ 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

alle test bestanden;)

fede s.
quelle
Ich frage mich nur, ist das Leerzeichen wirklich notwendig? Ich kann es nicht sicher sagen, da ich die Sprache nicht kenne oder keinen Dolmetscher habe.
Mama Fun Roll
@MamaFunRoll ja, nicht die beste Golfsprache! In der Forth-Tradition sind Leerzeichen nur Begrenzungszeichen.
fede s.
Oh, ich verstehe. Hier, hab eine positive Stimme.
Mama Fun Roll
Ja, ty! Jetzt mit meinem Kommentar Chaos zu brechen-überall priv!
fede s.
2

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

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

{... ... }anonyme Funktion , wo das rechte Argument dargestellt wird durch
⊃⍵erste Zeichen (Leerzeichen , wenn leer gibt)
'_'=1 , wenn gleich ‚underbar, 0 sonst
1+auswertet bis 2 , wenn anfänglicher underbar, 1 sonst
⎕NC⍵ Klassennamen ; -1 wenn ungültiger Name, 0 wenn nicht definiert (aber gültiger Name), 2-9 wenn definiert (und somit gültig)

Adam
quelle
1

Mathematica, 93 Bytes

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

Ich bin ehrlich gesagt nicht sicher , ob dies kann weiter golfed werden.

LegionMammal978
quelle
1

Perl, 34 + 1 = 35 Bytes

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

Verwendet die -p Flagge.

Erläuterung

$_=/^([^\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
ein Spaghetto
quelle
[_a-zA-Z]-> [^\W\d]Wenn Perl genauso funktioniert wie JavaScript, \w*
müssten
@ Downgoat Scheint gut zu funktionieren \w+.
ein Spaghetto
Spiele falsch füra
Downgoat
@ Downgoat Ah, richtig. Aha.
ein Spaghetto
1

Python, 84 - 10% = 76 Bytes

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

JavaScript ES7, 37 Byte

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

Probieren Sie es online aus

Wie es funktioniert:

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

Port von @ Dennis's Perl Antwort

undlrc
quelle
0

Ruby, 44 Bytes

->(s){s=~/^(_|\d)?\w*$/?$1?$1==?_?0.5:0:1:0}
Flambino
quelle
Sie brauchen keine Parens um die Parameter für Stabby Lambdas
Nicht, dass Charles
Auch wenn Sie einen Weg finden, dieses zusätzliche Ternär zu löschen, können Sie wahrscheinlich einige Bytes sparen. Vielleicht /^([a-z_]).../ianstatt/^(_|\d)?.../
Nicht dass Charles
@NotthatCharles D'oh ... du hast recht. Ich werde es näher betrachten, wenn ich eine Chance habe
Flambino
0

Ruby, 57 - 10% = 51,3 Bytes

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

Ein ziemlich naiver Ansatz

Flambino
quelle
51,3 Bytes wohlgemerkt. :)
Xesau
@ Xesau whoops - peinlich. Jetzt
behoben
Sie sparen eine große Menge an Bytes, wenn Sie eine ternäre Verkettung verwenden:->(s){s=~/^$|^\d|\W/?0:s=~/^_/?0.5:1}
Value Ink
@ KevinLau True - Ich habe bereits eine weitere Ruby-Antwort in diesem Sinne hinzugefügt (obwohl es auch nicht großartig ist)
Flambino
0

Lua, 82-10% = 73,8

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

Testfälle:

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
xaxa
quelle
Ich denke, Sie können STDIN verwenden, um mindestens 10 Bytes zu essen.
Undichte Nonne
0

Lua, 68 * .9 = 61,2 Bytes

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

Übernimmt Argumente in der Befehlszeile

Trebuchette
quelle