문자열을 읽기의 cs와 올바르게 비교하는 방법은 무엇입니까?

문자열을 읽기의 cs와 올바르게 비교하는 방법은 무엇입니까?

시나리오: yyyy-mm-dd파일에서 cs로 형식의 날짜를 읽습니다. 이 cs는 나중에 '현재 날짜' 매크로와 비교되어 특정 방식으로 몇 가지 인수를 외부 파일에 씁니다. 현재 날짜 매크로는 다음과 같습니다.

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

이는 의도한 대로 작동하므로 라벨링 작업에 적합합니다 \ref{yyyy-mm-dd}. 추가 항목이 없고 'd Today를 \TODAY사용하면 \def작동하지 않는 비교가 됩니다. etoolbox'는 \ifstrequal내가 이전에 사용했던 것이 아닙니다. 날짜가 변경될 때마다 나는 단일을 사용 \xdef하고 나중에 해당 매크로를 에 전달했으며 \ifx, 그것이 작동하도록 하려면 날짜를 추가하여 정의해야 했습니다 .편집하다놀랍게도 읽은 내용 뒤에 단일 공백이 삽입됩니다.

현재는 뭔가를 고치고 있는 것 같은데 어떻게든 깨뜨려서 지금은 전혀 일치하지 않습니다. 첫 번째 범인은 내 cmd가 강력해서 이를 수정하는 대신 \TwoDigits다시 변경했다는 것 입니다 . 후자는 사용자 수준 명령을 위한 것이므로 생략하겠습니다. 그러나 mwe의 결과는 나에게 명확하지 않습니다.\def\NewDocumentCommand

0.txt2001-01-01한 줄이 기록되고 출력이 닫힌 것처럼 한 줄이 포함되고 그 뒤에 새로운 줄이 포함됩니다.

질문:

  1. 문자열로 확장되어야 하는 것(매크로, cs, 명령?)을 비교하는 '올바른' 방법은 무엇입니까?
  2. \edef여기에서 작업 하면 어떨까요 \xdef? 완전한 확장이라고 생각했는데 실제로 이전에는 (내 버전 관리가 거의 없어서 이에 대한 mwe를 줄 수 없었습니다) 작동했습니다.
  3. 견고함의 중요성은 무엇입니까? 필요하거나, 의무적이거나, 관련이 없을 때 간단한 경험 법칙이 있나요?
  4. 그것은 와 함께 작동 xstring합니다\IfStrEqual 오직이 비교의 대괄호가 아닌 의 정의에 삽입된 경우 (예: )입니다 . 왜?\datemacro{\datemacro }
  5. \ifstrequal아마도 확장되지 않을 것입니다. 인수가 와 같은지 테스트하기 위해 명령에서 한 번 사용했습니다. &이것은 작동합니다. #1은 확장으로 간주되지 않는 입력이 되는 것입니까?

편집하다: 구분된 인수가 아닌 매크로에 사용되는 것을 잊어버렸습니다 \ifx. 죄송합니다.

예시 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}

예시 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}

답변1

\ifstrequal

문서에서 etoolbox:

\ifstrequal{⟨string⟩}{⟨string⟩}{⟨true⟩}{⟨false⟩}
두 문자열을 비교하여 동일하면 ⟨true⟩를 실행하고, 그렇지 않으면 ⟨false⟩를 실행합니다. 문자열은 테스트에서 확장되지 않으며 비교는 범주 코드에 구애받지 않습니다. ⟨string⟩ 인수의 제어 시퀀스 토큰은 토큰화 해제되어 문자열로 처리됩니다. 이 명령은 강력합니다.

따라서 다음과 정확히 동일하지 \ifstrequal{\testi}{...}않으면 true를 반환하지 않습니다....\testi 문자열로.

반면에,

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

을 반환 T하지만 \read줄 끝을 확인하여 생성된 트랄링 공간을 확인하세요.

\ifx

이는 기본 조건문이며 적절한 구문과 함께 사용해야 합니다. 확장 없이 토큰 \ifx AB을 비교합니다 . 그래서 와 비교할 것입니다 .AB\ifx{\DDD}...{\DDD

\ifcsequal

\ifcsequal{⟨csname⟩}{⟨csname⟩}{⟨true⟩}{⟨false⟩}
\ifdefequal제어 시퀀스 이름을 인수로 사용한다는 점을 제외 하면 비슷합니다 .

따라서 및 를 \ifcsequal{\testi}{\DDD}모두 확장하므로 두 개의 내장된 제어 시퀀스가 ​​모두 와 동일하기 때문에 false를 반환하는 것과 동일합니다 .\testi\DDD\ifcsequal{2001-01-01}{2001-01-01 }\relax

\ifdefequal

여기서 마침내 true를 반환하는 코드를 얻을 수 있습니다. 참고해서 사용하시면

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

그럼 \ifdefequal{\testiii}{\DDD}돌아올 것이다거짓, 첫 번째 레벨 확장만 살펴보기 때문입니다. 반면에 \edef버전이 작동합니다.

\IfStrEq

이는 (정상적인 조건에서) 인수를 완전히 확장하므로 \testiiii또는 둘 중 하나와의 비교가 \testiiii작동합니다.

견고성

의 견고성은 \ifstrequal전혀 관련이 없습니다. 글쎄요, 실제로는 완전히는 아닙니다. TeX 엔진이 지원한다면 \expanded(TeX Live 2019 출시와 함께 몇 주 안에 모두 지원될 예정입니다) 다음과 같습니다.

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

돌아올 것이며 이것이 작동하려면 T견고성이 결정적입니다.\ifstrequal

작동 테스트를 사용하십시오.

관련 정보