Wie vergleicht man einen String ordnungsgemäß mit einem CS aus einem Lesevorgang?

Wie vergleicht man einen String ordnungsgemäß mit einem CS aus einem Lesevorgang?

Das Szenario: Ein Datum in einem yyyy-mm-ddFormular aus einer Datei in eine CS lesen. Diese CS wird später mit einem Makro „aktuelles Datum“ verglichen, um einige Argumente auf eine bestimmte Weise in eine externe Datei zu schreiben. Das Makro „aktuelles Datum“ ähnelt dem von

% \def\TODAY{}
% \def\Today{\the\year-\TwoDigits{\the\month}-\TwoDigits{\the\day} }
\def\TODAY{\xdef\Today{\the\year-\TwoDigits{\the\month}-\TwoDigits{\the\day}}}

Das funktioniert für die Beschriftung, da \ref{yyyy-mm-dd}es wie vorgesehen funktioniert. Wenn man kein Extra hat \TODAYund dann \def'd Today verwendet, funktioniert es auch, der Vergleich funktioniert nicht. etoolbox's \ifstrequalist nicht das, was ich vorher verwendet habe. Immer wenn sich das Datum änderte, habe ich ein einzelnes verwendet \xdefund dieses Makro später an ein übergeben \ifx, und damit es funktioniert, musste ich das Datum mit einem angehängten definieren.bearbeiten„Read to my amazement“ fügt nach dem Gelesenen ein einzelnes Leerzeichen ein.

Momentan bin ich angeblich dabei, Dinge zu reparieren, aber ich habe es irgendwie kaputt gemacht, und jetzt passt es überhaupt nicht mehr. Der erste Übeltäter war, dass mein \TwoDigitscmd robust war. Ich habe es zurück in geändert, \defanstatt \NewDocumentCommandes zu beheben. Letzteres ist für Befehle auf Benutzerebene, also lasse ich das durchgehen. Aber die Ergebnisse des MWE sind mir nicht klar.

0.txtenthält eine Zeile mit 2001-01-01und dahinter eine Zeile new, als ob eine Zeile hineingeschrieben und die Ausgabe geschlossen worden wäre.

Die Fragen:

  1. Was ist die „richtige“ Art, Dinge (Makro, CS, Befehl?) zu vergleichen, die (sollten) in Zeichenfolgen erweitert werden?
  2. Warum funktioniert es hier nicht \edef? \xdefIch dachte, es wäre eine vollständige Erweiterung, und tatsächlich hat es vorher funktioniert (meine Versionskontrolle ist so gut wie nicht vorhanden, also ist mir das völlig egal).
  3. Welche Bedeutung hat Robustheit? Gibt es eine einfache Faustregel, wann sie notwendig, obligatorisch oder irrelevant ist?
  4. Es funktioniert mit xstring's\IfStrEqual nurwenn in die Definition von eingefügt wird \datemacround nicht in die Klammern des Vergleichs, also {\datemacro }. Warum?
  5. \ifstrequalwird angeblich nicht erweitert – ich habe es einmal in einem Befehl verwendet, um zu testen, ob ein Argument gleich ist &, das funktioniert – zählt es nicht als Erweiterung, wenn Nr. 1 zu der Eingabe wird?

bearbeiten: Ich habe vergessen, \ifxdass es für Makros verwendet wurde, nicht für abgegrenzte Argumente, tut mir leid.

Beispiel 1;

\documentclass{article}
\usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
\usepackage{etoolbox}
\newread\periods
\openin\periods=0.txt
\begin{document}\setlength\parindent{0pt}\fontsize{20}{20}\selectfont
\def\testi{2001-01-01}
\edef\testii{2001-01-01}
\def\testiii{2001-01-01 }
\edef\testiiii{2001-01-01 }
\global\read\periods to \DDD

\ifstrequal{\testi}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\DDD}{2001-01-01}{T\\}{F\\}% F

\ifstrequal{\testi}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\DDD}{\DDD}{T\\}{F\\}% T

\ifx{\testi}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testiii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\testiiii}{2001-01-01} T\\\else F\\\fi% F
\ifx{\DDD}{2001-01-01} T\\\else F\\\fi% F

\ifx{\testi}{\DDD} T\\\else F\\\fi% F
\ifx{\testii}{\DDD} T\\\else F\\\fi% F
\ifx{\testiii}{\DDD} T\\\else F\\\fi% F
\ifx{\testiiii}{\DDD} T\\\else F\\\fi% F
\ifx{\DDD}{\DDD} T\\\else F\\\fi% F

\ifcsequal{\testi}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\DDD}{\DDD}{T\\}{F\\}% F

\ifdefequal{\testi}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\testiiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\DDD}{\DDD}{T\\}{F\\}% T
\end{document}

Beispiel 2;

\documentclass{article}
\usepackage[top=1.5cm, bottom=0.6cm, hmargin=1.5cm]{geometry}
\usepackage{etoolbox,xstring}
\def\TwoDigits#1{\ifnum#1<10 0#1\else#1\fi}

\newcount\month
    \month 1\relax
\newcount\day
    \day 1\relax
\newread\periods
\openin\periods=0.txt
\global\read\periods to \DDD

\def\testi{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day}}%
\edef\testii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day}}%
\def\testiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%
\edef\testiiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%

\begin{document}\setlength\parindent{0pt}
DDD is \DDD.% space between cs and .

\ifstrequal{\testi}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\testiiii}{2001-01-01}{T\\}{F\\}% F
\ifstrequal{\DDD}{2001-01-01}{T\\}{F\\}% F

\ifstrequal{\testi}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifstrequal{\DDD}{\DDD}{T\\}{F\\}% T

\ifx\testi{2001-01-01} T\\\else F\\\fi% F
\ifx\testii{2001-01-01} T\\\else F\\\fi% F
\ifx\testiii{2001-01-01} T\\\else F\\\fi% F
\ifx\testiiii{2001-01-01} T\\\else F\\\fi% F
\ifx\DDD{2001-01-01} T\\\else F\\\fi% F

\ifx\testi\DDD T\\\else F\\\fi% F
\ifx\testii\DDD T\\\else F\\\fi% F
\ifx\testiii\DDD T\\\else F\\\fi% F
\ifx\testiiii\DDD T\\\else F\\\fi% T
\ifx\DDD\DDD T\\\else F\\\fi% T

\ifcsequal{\testi}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\testiiii}{\DDD}{T\\}{F\\}% F
\ifcsequal{\DDD}{\DDD}{T\\}{F\\}% F

\ifdefequal{\testi}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiii}{\DDD}{T\\}{F\\}% F
\ifdefequal{\testiiii}{\DDD}{T\\}{F\\}% T
\ifdefequal{\DDD}{\DDD}{T\\}{F\\}% T

\IfStrEq{\testi}{\DDD}{T\\}{F\\}% F
\IfStrEq{\testii}{\DDD}{T\\}{F\\}% F
\IfStrEq{\testi }{\DDD}{T\\}{F\\}% F
\IfStrEq{\testii }{\DDD}{T\\}{F\\}% F
\IfStrEq{\testiii}{\DDD}{T\\}{F\\}% T
\IfStrEq{\testiiii}{\DDD}{T\\}{F\\}% T
\IfStrEq{\DDD}{\DDD}{T\\}{F\\}% T

\end{document}

Antwort1

\ifstrequal

Aus der Dokumentation von etoolbox:

\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
Vergleicht zwei Zeichenfolgen und führt ⟨true⟩ aus, wenn sie gleich sind, und andernfalls ⟨false⟩. Die Zeichenfolgen werden im Test nicht erweitert und der Vergleich ist kategoriecodeunabhängig. Kontrollsequenztoken in einem der ⟨Zeichenfolgen⟩-Argumente werden detokenisiert und als Zeichenfolgen behandelt. Dieser Befehl ist robust.

Daher \ifstrequal{\testi}{...}wird true nicht zurückgegeben, es sei denn, ...es ist genau dasselbe wie\testi als Zeichenfolgen.

Andererseits,

\expandafter\ifstrequal\expandafter{\DDD}{2001-01-01 }{T}{F}

gibt zurück , aber beachten Sie den nachfolgenden Zwischenraum, der durch das Erkennen eines Zeilenendes Tentsteht .\read

\ifx

Dies ist ein primitiver Bedingungssatz und sollte mit der richtigen Syntax verwendet werden: \ifx ABvergleicht die Token Aund Bohne Erweiterung. Daher wird mit \ifx{\DDD}...verglichen .{\DDD

\ifcsequal

\ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}
Ähnlich wie \ifdefequal, außer dass es Steuersequenznamen als Argumente verwendet.

Somit werden sowohl als auch \ifcsequal{\testi}{\DDD}erweitert , es ist also dasselbe wie das Ausführen von , das „false“ zurückgibt, weil die beiden erstellten Steuersequenzen beide gleichwertig sind mit .\testi\DDD\ifcsequal{2001-01-01}{2001-01-01 }\relax

\ifdefequal

Hier erhalten Sie schließlich den Code, der true zurückgibt. Beachten Sie, dass, wenn Sie

\def\testiii{2001-\TwoDigits{\the\month}-\TwoDigits{\the\day} }%

dann \ifdefequal{\testiii}{\DDD}wird zurückkehrenFALSCH, weil es sich nur um die Erweiterung der ersten Ebene handelt. Andererseits \edefist die Version das, was funktioniert.

\IfStrEq

Dadurch werden die Argumente vollständig erweitert (unter normalen Bedingungen), sodass der Vergleich mit „oder“ \testiiiifunktioniert \testiiii.

Robustheit

Die Robustheit von \ifstrequalist völlig irrelevant. Naja, eigentlich nicht ganz. Wenn Ihre TeX-Engine dies unterstützt \expanded(alle werden es in ein paar Wochen mit der Veröffentlichung von TeX Live 2019 tun), dann etwas wie

\expanded{\ifstrequal}{\testiii}{\DDD}{T}{F}}

wird zurückkehren Tund die Robustheit \ifstrequalist entscheidend dafür, dass dies funktioniert.

Nutzen Sie den Arbeitstest.

verwandte Informationen