Entscheide dich für ein C-Integer-Literal
Zielsetzung
Entscheiden Sie anhand einer ASCII-Zeichenfolge, ob es sich um ein gültiges C-Integer-Literal handelt.
C ganzzahliges Literal
Ein ganzzahliges AC-Literal besteht aus:
Einer von:
0gefolgt von null oder mehr Oktalstellen (0-7)Eine Dezimalstelle ungleich Null, gefolgt von null oder mehr Dezimalstellen (
0-9)0Xoder0xgefolgt von einer oder mehreren hexadezimalen Ziffern (0-9,A-Funda-f)
optional gefolgt von einem von:
Eines von
Uoderu, das sind die "vorzeichenlosen" SuffixeEiner von
L,l,LLoderll, die die „lange“ und „long long“ Suffixe sindBeliebige Kombination der oben genannten in beliebiger Reihenfolge.
Beachten Sie, dass es beliebig viele Ziffern geben kann, obwohl C keine Ganzzahlen beliebiger Länge unterstützt. Auch wenn das Literal mit lund co den longTyp oder die Co überlaufen würde , wird es dennoch als gültiges Literal betrachtet.
Beachten Sie auch, dass es kein führendes Plus- oder Minuszeichen geben darf, da es nicht als Teil des Literal betrachtet wird.
Regeln
Es ist implementierungsdefiniert, um führende oder nachfolgende Leerzeichen zu akzeptieren.
Nicht-ASCII-Zeichenfolgen fallen in eine Situation, in der es egal ist.
Beispiele
Wahrheit
000742u42lu42UL19827489765981697847893769837689346573uLL(Ziffern können beliebig viele sein, auch wenn sie nicht zumunsigned long longTyp passen )0x8f6aa032838467beee3939428l(So kann derlongTyp)0XCa0(Sie können Fälle mischen)
Falsch
08(Nicht oktale Ziffer)0x(Eine Ziffer muss folgenXoderx)-42(Führende Signatur ist nicht Teil des Literal)42Ll(NurLLoderllgültig für denlong longTyp)42LLLL(Redundanter Typbezeichner)42Uu(Redundanter Typbezeichner)42Ulu(Redundanter Typbezeichner)42lul(Redundanter Typbezeichner)42H(Ungültiger Typbezeichner)0b1110010000100100001(Gültiges C ++, aber nicht gültiges C)HelloLeerer String
Ungolfed Lösung
Haskell
Erkennt keine führenden oder nachfolgenden Leerzeichen.
Rückkehr ()zum Erfolg. Sonst monadisches Versagen.
import Text.ParserCombinators.ReadP
decideCIntegerLit :: ReadP ()
decideCIntegerLit = do
choice [
do
'0' <- get
munch (flip elem "01234567"),
do
satisfy (flip elem "123456789")
munch (flip elem "0123456789"),
do
'0' <- get
satisfy (flip elem "Xx")
munch1 (flip elem "0123456789ABCDEFabcdef")
]
let unsigned = satisfy (flip elem "Uu")
let long = string "l" +++ string "L" +++ string "ll" +++ string "LL"
(unsigned >> long >> return ()) +++ (optional long >> optional unsigned)
eof
Antworten
Retina 0,8,2 , 60 59 Bytes
i`^(0[0-7]*|0x[\da-f]+|[1-9]\d*)(u)?(l)?(?-i:\3?)(?(2)|u?)$
Probieren Sie es online aus! Link enthält Testfälle. Bearbeiten: 1 Byte dank @FryAmTheEggMan gespeichert. Erläuterung:
i`
Match ohne Berücksichtigung der Groß- und Kleinschreibung.
^(0[0-7]*|0x[\da-f]+|[1-9]\d*)
Beginnen Sie entweder mit Oktal, Hex oder Dezimal.
(u)?
Optionaler vorzeichenloser Bezeichner.
(l)?
Optionaler Längenbezeichner.
(?-i:\3?)
Optional können Sie den Fall des Längenangaben empfindlich wiederholen.
(?(2)|u?)$
Wenn noch kein vorzeichenloser Bezeichner vorhanden ist, besteht vor dem Ende des Literal eine weitere Chance für einen optionalen Bezeichner.
Perl 5 -p , 65 61 Bytes
@NahuelFouilleul rasierte 4 Bytes
$_=/^(0[0-7]*|0x\p{Hex}+|[1-9]\d*)(u?l?l?|l?l?u?)$/i*!/lL|Ll/
Probieren Sie es online aus!
Java 8 / Scala Polyglot, 89 79 Byte
s->s.matches("(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\\d*|0x[\\da-f]+)(u?l?l?|l?l?u?)")
-10 Bytes dank @NahuelFouilleul
Probieren Sie es online in Java 8 aus.
Probieren Sie es online in Scala aus (außer mit =>statt ->- dank @TomerShetah ).
Erläuterung:
s-> // Method with String parameter and boolean return-type
s.matches( // Check whether the input-string matches the regex
"(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\\d*|0x[\\da-f]+)(u?l?l?|l?l?u?)")
Regex Erklärung:
In Java String#matchesfügt die Methode implizit einen führenden und einen nachfolgenden hinzu ^...$, um der gesamten Zeichenfolge zu entsprechen. Der reguläre Ausdruck lautet also:
^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$
(?! ) # The string should NOT match:
^ .* # Any amount of leading characters
( ) # Followed by:
Ll # "Ll"
|lL # Or "lL"
# (Since the `?!` is a negative lookahead, it acts loose from the
# rest of the regex below)
(?i) # Using case-insensitivity,
^ ( # the string should start with:
0 # A 0
[0-7]* # Followed by zero or more digits in the range [0,7]
| # OR:
[1-9] # A digit in the range [1,9]
\d* # Followed by zero or more digits
| # OR:
0x # A "0x"
[ ]+ # Followed by one or more of:
\d # Digits
a-f # Or letters in the range ['a','f']
)( # And with nothing in between,
)$ # the string should end with:
u? # An optional "u"
l?l? # Followed by no, one, or two "l"
| # OR:
l?l? # No, one, or two "l"
u? # Followed by an optional "u"
C # (.NET Core) ,
197
191 Bytes
@wellnhof rasiert 6bytes:
using c=System.Console;class P{static void Main(){c.WriteLine(System.Text.RegularExpressions.Regex.IsMatch(c.ReadLine(),@"^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$"));}}
Original:
using c=System.Console;using System.Text.RegularExpressions;class P{static void Main(){c.WriteLine(Regex.IsMatch(c.ReadLine(),@"^(?!.*(Ll|lL))(?i)(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)$"));}}
Probieren Sie es online aus!
Python 3 , 103 Bytes
import re;re.compile("^(0[0-7]*|[1-9]\d*|0[xX][\dA-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$").match
Probieren Sie es online aus!
nur eine einfache Regex, wahrscheinlich sehr suboptimal
Gibt ein Übereinstimmungsobjekt für wahr und Keine für falsch zurück. Die Eingabe enthält möglicherweise keine umgebenden Leerzeichen
-3 Bytes dank Digital Trauma (auf meiner Retina-Antwort)
-1 Byte dank FryAmTheEggman (auf meiner Retina-Antwort)
-3 Bytes dank pxeger
Retina 0,8,2 , 73 Bytes
^(0[0-7]*|[1-9]\d*|0[xX][\dA-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$
Probieren Sie es online aus!
Genau die gleiche Regex, die ich verwendet habe. Ich bin mir sicher, dass dies bei der ersten Verwendung von Retina mit einigen Retina-Golf-Dingen optimiert werden kann!
-3 Bytes dank Digital Trauma
-1 Bytes dank FryAmTheEggman
JavaScript (ES6), 77 Byte
s=>/^(0x[\da-f]+|0[0-7]*|[1-9]\d*)(u?l?l?|l?l?u?)$/i.test(s)&!/Ll|lL/.test(s)
Probieren Sie es online aus!
Wie?
Bei der ersten Regex wird die Groß- und Kleinschreibung nicht berücksichtigt. Die einzigen ungültigen Muster, die auf diese Weise nicht herausgefiltert werden können, sind "Ll"und "lL". Deshalb verwenden wir einen zweiten regulären Ausdruck, bei dem die Groß- und Kleinschreibung beachtet wird.
Holzkohle , 76 Bytes
≔⊟Φ³¬⌕↧θ…0xιη≔✂↧θη⁻LθL⊟Φ⪪”{“↧←;⭆δa”¶⁼ι↧…⮌θLι¹ζ›∧⁺Lζ¬⊖η⬤ζ№E∨×⁸ηχ⍘λφι∨№θLl№θlL
Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Erläuterung:
≔⊟Φ³¬⌕↧θ…0xιη
Suchen Sie die Länge des längsten Präfixes von 0xin der Eingabe in Kleinbuchstaben.
≔✂↧θη⁻LθL⊟Φ⪪”{“↧←;⭆δa”¶⁼ι↧…⮌θLι¹ζ
Scheibe aus dem Präfix und prüfen auch für einen Klein Suffix ull, ul, lluoder lu, und wenn ja , dann schneiden dass Off als auch.
›...∨№θLl№θlL
Die ursprüngliche Eingabe darf kein Lloder enthalten lL.
∧⁺Lζ¬⊖η
Die in Scheiben geschnittene Zeichenfolge darf nicht leer sein, es sei denn, das Präfix war 0.
⬤ζ№E∨×⁸ηχ⍘λφι
Konvertieren Sie die Präfixlänge zu 10, 8oder in 16geeigneter Weise , nehmen Sie dann , dass viele Basis 62 Ziffern und prüfen, ob alle verbleibenden Kleinbuchstaben Zeichen einer dieser Ziffern sind.
05AB1E , 63 61 62 Bytes
„Uuõª„LLæDl«âDí«JéRʒÅ¿}нõ.;Ðć_ilDć'xQiA6£мÐþQë\7ÝKõQë\þQ}sõÊ*
Ohne Regexes ist das nicht so einfach ..: / Kann aber definitiv ein bisschen mehr Golf spielen.
1 Byte als Bug-Fix für Eingaben wie "u", "l", "LL"usw. (Dank für bemerken @Neil )
Probieren Sie es online aus oder überprüfen Sie alle Testfälle .
Erläuterung:
„Uu # Push string "Uu"
õª # Convert it to a list of characters, and append an empty string:
# ["U","u",""]
„LL # Push string "LL"
æ # Take its powerset: ["","L","L","LL"]
Dl # Create a lowercase copy: ["","l","l","ll"]
« # Merge the lists together: ["","L","L","LL","","l","l","ll"]
â # Create all possible pairs of these two lists
Dí # Create a copy with each pair reversed
« # Merge the list of pairs together
J # Join each pair together to a single string
éR # Sort it by length in descending order
Wir haben jetzt die Liste:
["llu","LLu","llU","LLU","ull","uLL","Ull","ULL","ll","LL","lu","lu","Lu","Lu","lU","lU","LU","LU","ll","LL","ul","ul","uL","uL","Ul","Ul","UL","UL","l","l","L","L","u","u","U","U","l","l","L","L","u","u","U","U","","","",""]
ʒ # Filter this list by:
Å¿ # Where the (implicit) input ends with this string
}н # After the filter: only leave the first (longest) one
õ.; # And remove the first occurrence of this in the (implicit) input
ÐD # Triplicate + duplicate (so there are 4 copies on the stack now)
ć # Extract head; pop and push remainder-string and first character
# separated to the stack
_i # If this first character is a 0:
l # Convert the remainder-string to lowercase
D # Duplicate it †¹
ć # Extract head again
'xQi '# If it's equal to "x":
A # Push the lowercase alphabet
6£ # Only leave the first 6 characters: "abcdef"
м # Remove all those characters from the string
Ð # Triplicate it †²
þ # Only keep all digits in the copy
Q # And check that the two are still the same
# (thus it's a non-negative integer without decimal .0s)
ë # Else:
\ # Discard the remainder-string
7Ý # Push list [0,1,2,3,4,5,6,7]
K # Remove all those digits
õQ # Check what remains is an empty string
ë # Else:
\ # Discard the remainder-string
þ # Only keep all digits
Q # And check that the two are still the same
# (thus it's a non-negative integer without decimal .0s)
}s # After the if-else: Swap the two values on the stack
# (this will get the remaining copy of †² for "0x" cases,
# or the remaining copy of †¹ for other cases)
õÊ # Check that this is NOT an empty string
* # And check that both are truthy
# (after which the result is output implicitly)
AWK , 86 Bytes
{print/^(0[0-7]*|[1-9][0-9]*|0[xX][0-9A-Fa-f]+)([uU](L|l|LL|ll)?|(L|l|LL|ll)[uU]?)?$/}
Probieren Sie es online aus!
Druckt einfach wahrheitsgemäß oder falsch, je nachdem, ob die Eingabezeile mit dem regulären Ausdruck übereinstimmt oder nicht. Akzeptiert keine führenden oder nachfolgenden Leerzeichen.
Haskell , 169 Bytes
import Data.Char
s!p=s>""&&dropWhile p s`elem`do u<-["","u","U"];l<-"":words"L l LL ll";[u++l,l++u]
f('0':x:s)|elem x"xX"=s!isHexDigit|1<2=(x:s)!isOctDigit
f s=s!isDigit
Probieren Sie es online aus!
Ruby , 67 Bytes
->s{/^(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)?$/i=~s&&/Ll/!~s}
Probieren Sie es online aus!
Elixier , 74 Bytes
&(&1=~~r/^(0[0-7]*|[1-9]\d*|0x[\da-f]+)(u?l?l?|l?l?u?)?$/i&&!(&1=~~r/Ll/))
Probieren Sie es online aus!