Regulärer Ausdruck unescaped doppelte Anführungszeichen in CSV-Datei zu finden
Frage
Was wäre ein regulärer Ausdruck Sätze von 2 unescaped doppelte Anführungszeichen zu finden, die in den Spalten werden durch doppelte Anführungszeichen in einer CSV-Datei?
aufrechnenKein Spiel:
"asdf","asdf"
"", "asdf"
"asdf", ""
"adsf", "", "asdf"
Match:
"asdf""asdf", "asdf"
"asdf", """asdf"""
"asdf", """"
Lösung
Versuchen Sie folgendes:
(?m)""(?![ \t]*(,|$))
Erklärung:
(?m) // enable multi-line matching (^ will act as the start of the line and $ will act as the end of the line (i))
"" // match two successive double quotes
(?! // start negative look ahead
[ \t]* // zero or more spaces or tabs
( // open group 1
, // match a comma
| // OR
$ // the end of the line or string
) // close group 1
) // stop negative look ahead
Also, im Klartext: „Spiel zwei aufeinanderfolgende doppelte Anführungszeichen, nur dann, wenn sie nicht über ein Komma oder End-of-the-line vor ihnen gegebenenfalls mit Leerzeichen und Tabulatoren zwischen“ .
(i) abgesehen davon, daß die normale Start-of-the-Zeichenfolge und End-of-the-Zeichenfolge Meta-Zeichen.
Andere Tipps
Aufgrund der Komplexität des Problems hängt die Lösung auf dem Motor Sie verwenden. Dies, weil sie zu lösen, müssen Sie hinter verwenden aussehen und nach vorne schauen und jeder Motor ist nicht das gleiche dies.
Meine Antwort wird mit Ruby-Engine. Die Prüfung ist nur ein RegEx aber ich den ganzen Code hier aus für eine bessere erklären es.
Hinweis, dass aufgrund Ruby-RegEx-Engine (oder mein Wissen), optional Vorgriff / hinten nicht möglich ist. Also brauche ich ein kleines Problem der Räume vor und nach dem Komma.
Hier ist mein Code:
orgTexts = [
'"asdf","asdf"',
'"", "asdf"',
'"asdf", ""',
'"adsf", "", "asdf"',
'"asdf""asdf", "asdf"',
'"asdf", """asdf"""',
'"asdf", """"'
]
orgTexts.each{|orgText|
# Preprocessing - Eliminate spaces before and after comma
# Here is needed if you may have spaces before and after a valid comma
orgText = orgText.gsub(Regexp.new('\" *, *\"'), '","')
# Detect valid character (non-quote and valid quote)
resText = orgText.gsub(Regexp.new('([^\"]|^\"|\"$|(?<=,)\"|\"(?=,)|(?<=\\\\)\")'), '-')
# resText = orgText.gsub(Regexp.new('([^\"]|(^|(?<=,)|(?<=\\\\))\"|\"($|(?=,)))'), '-')
# [^\"] ===> A non qoute
# | ===> or
# ^\" ===> beginning quot
# | ===> or
# \"$ ===> endding quot
# | ===> or
# (?<=,)\" ===> quot just after comma
# \"(?=,) ===> quot just before comma
# (?<=\\\\)\" ===> escaped quot
# This part is to show the invalid non-escaped quots
print orgText
print resText.gsub(Regexp.new('"'), '^')
# This part is to determine if there is non-escaped quotes
# Here is the actual matching, use this one if you don't want to know which quote is un-escaped
isMatch = ((orgText =~ /^([^\"]|^\"|\"$|(?<=,)\"|\"(?=,)|(?<=\\\\)\")*$/) != 0).to_s
# Basicall, it match it from start to end (^...$) there is only a valid character
print orgText + ": " + isMatch
print
print ""
print ""
}
Wenn der Code druckt ausgeführt:
"asdf","asdf"
-------------
"asdf","asdf": false
"","asdf"
---------
"","asdf": false
"asdf",""
---------
"asdf","": false
"adsf","","asdf"
----------------
"adsf","","asdf": false
"asdf""asdf","asdf"
-----^^------------
"asdf""asdf","asdf": true
"asdf","""asdf"""
--------^^----^^-
"asdf","""asdf""": true
"asdf",""""
--------^^-
"asdf","""": true
Ich hoffe, dass ich Ihnen eine Vorstellung hier, dass Sie mit anderem Motor und Sprache verwenden können.
".*"(\n|(".*",)*)
sollte funktionieren, ich denke ...
Für einzeilige entspricht:
^("[^"]*"\s*,\s*)*"[^"]*""[^"]*"
oder für Multi-line:
(^|\r\n)("[^\r\n"]*"\s*,\s*)*"[^\r\n"]*""[^\r\n"]*"
Bearbeiten / Hinweis: Abhängig von dem Regex-Engine verwendet, Sie Lookbehinds und andere Sachen zu machen, die Regex schlanken nutzen könnten. Dies sollte aber in den meisten regex Motoren gut funktionieren.
Versuchen Sie, diesen regulären Ausdruck:
"(?:[^",\\]*|\\.)*(?:""(?:[^",\\]*|\\.)*)+"
Das wird passen jede Zeichenfolge in Anführungszeichen mit mindestens einem Paar unescaped doppelte Anführungszeichen.