Ich versuche eine StringScanner
verwenden, um eine Zeichenfolge in Tokens für die Verarbeitung später zu analysieren. Alles lief gut, bis ich die Syntaxanalyse der Regex-Syntax getestet habe. Regexen wie folgt aussehen:StringScanner entspricht einer Zeichenfolge, als wäre es eine Position zurück
r|hello|gmi
r:there|there:gmi
r/:(?=[jedi])[sith]:/gmi
r!hello!gmi
Das heißt, r
, gefolgt von |
(oder ein paar andere Zeichen, aber das ist jetzt irrelevant), durch den Körper der Regex gefolgt - die Escape-Zeichen enthalten kann, wie \|
und \\
- dann noch ein |
, und dann die Flags der Regex.
für regex Literale zu betrachten, ich bin mit Code, der eine ganze Menge, wie folgt aussieht:
require 'strscan'
scanner = StringScanner.new('r|abc| ')
puts "pre-regex: #{scanner.inspect}"
puts "got a char: #{scanner.getch} (res: #{scanner.inspect})"
divider = scanner.getch
puts "got divider: #{divider.inspect}"
puts "mid-regex: #{scanner.inspect}"
# this bit still fails even if you replace `#{divider}' with `|'
res = scanner.scan_until(/(?<![^\\]\\)#{divider}[a-z]*/)
puts "post-regex: #{scanner.inspect}"
if scanner.skip(/\s+/)# || scanner.skip(/;-.*?-;/m)
puts "Success! #{res}"
else
puts "Fail. Ended at: #{scanner.inspect}"
puts "(res was #{res.inspect})"
end
Hier habe ich es so viel abgespeckte, wie ich denke, Ich kann das Problem deutlich zeigen. Im echten Code ist es Teil eines sehr großen Codes, dessen große Mehrheit nicht relevant ist. Ich habe den Fehler auf diesen Teil eingegrenzt - Sie können den Link verwenden, um zu sehen, dass es da ist - aber ich kann nicht herausfinden, warum dies nicht bis zur nächsten Instanz von |
richtig scannt, dann die Flags zurückgeben.
Als eine Randnotiz, wenn es eine bessere Möglichkeit gibt, dies zu tun, lass es mich wissen. Ich habe festgestellt, dass ich ganz gerne StringScanner
, aber das könnte sein, weil ich mit Regexen besessen bin, bis zu dem Punkt, dass ich sie Regexen nennen.
TL; DR: Warum passt StringScanner
scheinbar, als ob seine Position ein Zeichen zurück war, und wie kann ich es richtig machen?
Ich habe diesen Kommentar gelöscht, weil es falsch ist. Aber ich frage mich, ob es ungerade Anzahl (mehr als 3) von Paaren von Backslashes vor dem Teiler gibt, was wird passieren? – Aetherus
Wenn es drei gibt, ändere ich die Regex zu '(?