Regulärer Ausdruck unescaped doppelte Anführungszeichen in CSV-Datei zu finden

StackOverflow https://stackoverflow.com/questions/1601780

  •  05-07-2019
  •  | 
  •  

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?

aufrechnen

Kein Spiel:

"asdf","asdf"
"", "asdf"
"asdf", ""
"adsf", "", "asdf"

Match:

"asdf""asdf", "asdf"
"asdf", """asdf"""
"asdf", """"
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top