Optimieren Sie lange Listen fester String-Alternativen in Regex

Lesezeit: 7 Minuten

Optimieren Sie lange Listen fester String Alternativen in
Haniyeh Asemi

Ich habe einen Ausdruck zum Auswählen von Zeiten in einigen Zeitzonen, ich erwähne meinen Ausdruck im Folgenden:

/(\d+)(?:[.: ](\d\d))*\s*([aApP][.: ]?[mM][.: ]?|o'clock |o’clock)*\s*(PT|AT|PST|PDT|UTC|EST)/gm;

In diesem Ausdruck verwende ich einfach PT|AT|PST|PDT|UTC|EST Zeitzonen, aber ich möchte alle Listen basierend auf hinzufügen Abkürzungen für Zeitzonen – Weltweite Liste. Soll ich alle Listen in den Ausdruck einfügen? Gibt es eine bessere Lösung?

  • Da ist ein Weg! Es gibt Flags, um signifikante Leerzeichen zu deaktivieren und dann jedes “Atom” der Regex in eine separate Zeile zu setzen, mit einem erklärenden Kommentar daneben (ähnlich wie einige Code-Golf-Antworten erklärt werden). Ich habe das vor ein paar Jahren einmal auf einer Website gesehen, aber ich habe das Lesezeichen nicht zur Hand. Wenn ich es finde, komme ich zurück, um es zu posten (es sei denn, jemand kommt mir zuvor).

    – Tom

    6. Juli 2021 um 17:20 Uhr

  • Ich möchte hinzufügen, dass dies mit einer Regex “harter Modus” ist. Sie können es vielleicht zum Laufen bringen, aber wie Sie bemerkt haben, ist es nicht besonders klar. Es ist wahrscheinlich einfacher, die ursprüngliche Zeichenfolge in Teile zu zerlegen und dann eine einfachere Logik oder sogar einen einfachen Zeichenfolgenabgleich zu verwenden, um diese Teile zu validieren.

    – Tom

    6. Juli 2021 um 17:22 Uhr

  • |o'clock |o’clock kann einfach sein |o['’]clock. Was die Liste der Zeitzonenabkürzungen betrifft, ja, Sie müssen einen riesigen booleschen Ausdruck erstellen oder [A-Z]{1,5}\b würde wohl reichen.

    – AffeZeus

    6. Juli 2021 um 17:38 Uhr

  • Toms Punkt ist (IMO), dass, wenn Regex Ihr Hammer ist, alles wie ein Daumen aussieht. Miniaturisierte, fokussierte Mini-Sprachen/-Parser sind oft eine sauberere Lösung.

    – David Newton

    6. Juli 2021 um 17:41 Uhr


  • @Tom Angesichts der Tatsache, wie einfach es ist, dies zu überprüfen /x Flag wird nicht unterstützt Ich bin davon ausgegangen, dass Sie nicht wussten, dass diese Frage mit Javascript gekennzeichnet ist. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…. Sie könnten jedoch eine Regex-Zeichenfolge erstellen und verketten, wie Sie es gemäß den String-Verkettungsregeln von JS wünschen.

    – AffeZeus

    6. Juli 2021 um 17:42 Uhr


Optimieren Sie lange Listen fester String Alternativen in
Wiktor Stribiżew

Sie können einen Regex-Versuch aus den Wörtern auf der Website MyRegexTester.com erstellen:

  1. Holen Sie sich die Liste aller Zeitzonen von der Site, der Sie vertrauen, als Liste mit Wörtern, die jeweils in einer eigenen Zeile stehen
  2. Gehe zu https://www.myregextester.com/index.php
  3. Auswählen WORDLIST aus dem Dropdown-Feld rechts unten HIGHLIGHT-ÜBEREINSTIMMUNGEN Kontrollkästchen
    Geben Sie hier die Bildbeschreibung ein
  4. Fügen Sie die Liste der Zeitzonenzeichenfolgen ein und klicken Sie Geben Sie hier die Bildbeschreibung ein

Sie erhalten so etwas wie

^(?:A(?:C(?:WS|[DS])?T|DT|E[DS]?T|FT|K[DS]T|LMT|M[S]?T|NAS?T|QTT|RT|ST|W[DS]T|Z(?:OS|[OS])?T|oE|T)|B(?:RS|[NORST])T|C(?:AS|ES|H(?:A[DS]|OS|[OU])|ID?S|LS|hS|[ACDEKLOSVX])?T|D(?:AV|DU)T|E(?:ASS?|ES|GS|[ACDEGS])?T|F(?:JS|KS|[EJKN])T|G(?:A[LM]|IL|[EFMSY])T|H(?:OVS?|[DKS])T|I(?:R(?:KS|[DKS])|[CDOS])T|JST|K(?:OS|RAS?|UY|[GS])T|L(?:H[DS]|IN)T|M(?:A(?:GS|[GRW])T|DT|HT|MT|S[DKT]|UT|VT|YT|T)|N(?:FD|OVS?|Z[DS]|[CDFPRSU])T|O(?:MSS?|RA)T|P(?:ETS?|HO|M[DS]|ON|YS|[DEGHKSWY])?T|QYZT|R(?:OT|E)T|S(?:A[KMS]|RE|YO|[BCGRS])T|T(?:AH|OS|[FJKLMORV])T|U(?:LAS?T|TC|YS?T|ZT)|V(?:LAS?|OS|[EU])T|W(?:A(?:RS|[KS])?T|ES?T|FT|GS?T|I(?:TA|[BT])|ST|T)|Y(?:A(?:KS|[KP])|EKS?)T|[ABCDEFGHIKLMNOPQRSTUVWXYZ])$

Diese Codes 244 Zeitzonen.

Jetzt ist es an der Zeit, die endgültige Regex zu erstellen. Nehmen Sie die Anker von oben heraus, Sie brauchen die nicht ^ und $ wenn das Muster in der Mitte einer anderen Regex verwendet wird.

const tz = "(?:A(?:C(?:WS|[DS])?T|DT|E[DS]?T|FT|K[DS]T|LMT|M[S]?T|NAS?T|QTT|RT|ST|W[DS]T|Z(?:OS|[OS])?T|oE|T)|B(?:RS|[NORST])T|C(?:AS|ES|H(?:A[DS]|OS|[OU])|ID?S|LS|hS|[ACDEKLOSVX])?T|D(?:AV|DU)T|E(?:ASS?|ES|GS|[ACDEGS])?T|F(?:JS|KS|[EJKN])T|G(?:A[LM]|IL|[EFMSY])T|H(?:OVS?|[DKS])T|I(?:R(?:KS|[DKS])|[CDOS])T|JST|K(?:OS|RAS?|UY|[GS])T|L(?:H[DS]|IN)T|M(?:A(?:GS|[GRW])T|DT|HT|MT|S[DKT]|UT|VT|YT|T)|N(?:FD|OVS?|Z[DS]|[CDFPRSU])T|O(?:MSS?|RA)T|P(?:ETS?|HO|M[DS]|ON|YS|[DEGHKSWY])?T|QYZT|R(?:OT|E)T|S(?:A[KMS]|RE|YO|[BCGRS])T|T(?:AH|OS|[FJKLMORV])T|U(?:LAS?T|TC|YS?T|ZT)|V(?:LAS?|OS|[EU])T|W(?:A(?:RS|[KS])?T|ES?T|FT|GS?T|I(?:TA|[BT])|ST|T)|Y(?:A(?:KS|[KP])|EKS?)T|[ABCDEFGHIKLMNOPQRSTUVWXYZ])"
const regex = new RegExp(String.raw`(\d+)(?:[.: ](\d\d))*\s*([aApP][.: ]?[mM][.: ]?|o['’]clock)*\s*${tz}`, 'gm');
console.log(regex.source)

Ich bin mir nicht sicher, ob die Regex am Ende für Sie funktionieren wird, sehen Sie seine Demo onlineaber jetzt sehen Sie, wie Sie eine Sammlung von wörtlichen Zeichenfolgenmustern in einem Regex-Muster optimal verwenden können.

Um Regex-Versuche dynamisch in Ihrem Code zu erstellen, benötigen Sie etwas wie trie-regex. Es gibt andere Anwendungen, die in der Lage sind, Regex-Versuche aus Stringlisten zu erstellen.

Unten können Sie einen Regex-Trie für Ihre gegebene, durch Komma oder Zeilenumbruch getrennte Wortliste generieren:

!function(){return function t(e,n,r){function i(s,u){if(!n[s]){if(!e[s]){var c="function"==typeof require&&require;if(!u&&c)return c(s,!0);if(o)return o(s,!0);var f=new Error("Cannot find module '"+s+"'");throw f.code="MODULE_NOT_FOUND",f}var a=n[s]={exports:{}};e[s][0].call(a.exports,function
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <p>Add the comma or linebreak separated words to the text area and click <i>Generate</i>.</p>
  <textarea id="inputdata"></textarea>
  <br/>
  <button id="run">Generate</BUTTON>
  <pre><code id="result" /></pre>
</form>

Nachdem ich viel nach dem Schreiben einer nützlichen Regex für alle Zeitzonen gesucht und schließlich die folgende Regex geschrieben habe, hoffe ich, dass dies anderen hilft:

const tz = "(?:A(?:C(?:WS|[DS])?T|DT|E[DS]?T|FT|K[DS]T|LMT|M[S]?T|NAS?T|QTT|RT|ST|W[DS]T|Z(?:OS|[OS])?T|oE|T)|B(?:RS|[NORST])T|C(?:AS|ES|H(?:A[DS]|OS|[OU])|ID?S|LS|hS|[ACDEKLOSVX])?T|D(?:AV|DU)T|E(?:ASS?|ES|GS|[ACDEGS])?T|F(?:iS|KS|[EiKN])T|G(?:A[LM]|IL|[EFMSY])T*\\s*(?:(?:([+ -][0-9]{1,4})(?:[.:](\\d\\d)?)?)?)|H(?:OVS?|[DKS])T|I(?:R(?:KS|[DKS])|[CDOS])T|iST|K(?:OS|RAS?|UY|[GS])T|L(?:H[DS]|IN)T|M(?:A(?:GS|[GRW])T|DT|HT|MT|S[DKT]|UT|VT|YT|T)|N(?:FD|OVS?|Z[DS]|[CDFPRSU])T|O(?:MSS?|RA)T|P(?:ETS?|HO|M[DS]|ON|YS|[DEGHKSWY])?T|QYZT|R(?:OT|E)T|S(?:A[KMS]|RE|YO|[BCGRS])T|T(?:AH|OS|[FiKLMORV])T|U(?:LAS?T|TC*\\s*([+ -][0-9]{1,4}(?:[.:](\\d\\d))?)|YS?T|ZT)|V(?:LAS?|OS|[EU])T|W(?:A(?:RS|[KS])?T|ES?T|FT|GS?T|I(?:TA|[BT])|ST|T)|Y(?:A(?:KS|[KP])|EKS?)T)"
const numbers = "(one|two|three|four|five|six|seven|eight|nine|ten|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten)"
const partOfDay = "(morning|afternoon|evening)"
const timeExpression = new RegExp(String.raw `\d{1,2}(?:[.:](\d\d))*\s*([aApP][.: ]?[mM][.: ]?|o['’]clock|afternoon|\d{2})*\s* ${tz}|${numbers} ${partOfDay} ${tz}`, 'gm');

994940cookie-checkOptimieren Sie lange Listen fester String-Alternativen in Regex

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy