확장 가능한 방식으로 문자열에서 특정 문자의 발생 횟수 계산

확장 가능한 방식으로 문자열에서 특정 문자의 발생 횟수 계산

이 질문문자열에서 특정 문자의 발생 횟수를 계산하는 방법을 보여줍니다. 확장 가능한 방식으로 특정 문자 목록(하나뿐 아니라)에 대해 수행하고 싶습니다.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\countsep}{r[] m}{
    % CODE HERE
}
\ExplSyntaxOff

\begin{document}
\countsep[-+]{This-is-a+test} % Count the number of - and + in the string (3)
\countsep[-+]{T+h+i+s-is-a-test} % Count the number of - and + in the string (6)
\end{document}

답변1

\documentclass{article}

\def\countsep#1#2{\the\numexpr0\countsepy#1\Endlist#2\Endcount}
\def\countsepy#1#2\Endlist#3\Endcount{\countsepz#1#3\Endcount
  \ifx\relax#2\relax\relax\else\countsepy#2\Endlist#3\Endcount\fi}
\def\countsepz#1#2#3\Endcount{\ifx#1#2+1\fi
  \ifx\relax#3\relax\else\countsepz#1#3\Endcount\fi}

\begin{document}
\countsep{-}{This-is-a+test} % Count the number of - in the string (2)
\countsep{+}{This-is-a+test} % Count the number of + in the string (1)
\countsep{-+}{This-is-a+test} % Count the number of - and + in the string (3)

\edef\z{\countsep{-+}{T+h+i+s-is-a-test}}
\z
\end{document}

여기에 이미지 설명을 입력하세요

답변2

다음은 LuaLaTeX 기반 솔루션입니다 \countsep. 해결책은해결책나는 ~에게 주었다이전 쿼리OP 게시물에서 언급되었습니다. \countsep확장 가능하기 때문에 확장 \directlua가능 \luastring합니다.

검색 문자열과 대상 문자열 모두 일반 UTF8로 인코딩된 문자를 포함할 수 있다는 점을 자세히 살펴보세요.

여기에 이미지 설명을 입력하세요

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for '\luastring' macro
\newcommand\countsep[2]{\directlua{%
   _ , count = unicode.utf8.gsub ( "#2" , "["..\luastring{#1}.."]" , "" )
   tex.sprint ( count ) }}

\def\yy{äÖÜß}
\def\zz{ßT+h+i+s-is-a-testäÖÜß}
\edef\z{\countsep{\yy}{\zz}}

\begin{document}
\countsep{""}{This-is-a+test} % result: 0
\countsep{-+}{This-is-a+test} % result: 3
\countsep{-+}{T+h+i+s-is-a-test} % result: 6
\countsep{\yy}{\zz\zz} % result: 10
\z % result: 5
\end{document}

답변3

다음은 etl. 나는 그것에 대해 강력히 조언하지만 귀하의 질문에 괄호 안에 필수 인수를 사용합니다. 비표준 인수를 사용하는 것은 []일반적으로 선택적 인수이므로 권장되지 않습니다. 여기서는 구문 분석 오버헤드에 대한 타당한 이유가 없습니다.

언급할 사항:

  • 이는 실제로 토큰 목록에서 발생 횟수를 계산한다고 가정합니다(문자열화 없음).
  • 이는 중괄호 안의 구분 기호가 계산된다고 가정합니다(중첩된 문자를 + \vincent_count_tokens_in:nn로 변경하지 않는 경우 \use_none:nn).
  • 지정된 구분 기호 중 하나가 공백이면 올바르게 계산됩니다.
  • 이는 비UTF8 엔진(pdfTeX)의 비ASCII 구분 기호에는 작동하지 않습니다. 그렇지 않으면 모든 엔진에서 작동합니다.
\documentclass{article}
\usepackage{xparse, etl}

\ExplSyntaxOn
\etl_new_if_in:Nnn \__vincent_if_contains_space:n { ~ } { T }
\cs_new:Npn \vincent_count_tokens_in:nn #1#2
  {
    \int_eval:w 0
    \etl_act:nennn
      \__vincent_count_tokens_in:nN
      {
        \__vincent_if_contains_space:nT {#1} { + \c_one_int }
        \use_none:n
      }
      { + \vincent_count_tokens_in:nn }
      {#1}
      {#2}
    \scan_stop:
  }
\cs_generate_variant:Nn \etl_act:nnnnn { ne }
\cs_new:Npn \__vincent_count_tokens_in:nN #1#2
  { \etl_token_if_in:nNT {#1} #2 { + \c_one_int } }
\NewExpandableDocumentCommand{\countsep}{r[] m}
  { \vincent_count_tokens_in:nn {#1} {#2} }
\ExplSyntaxOff

\begin{document}
\countsep[-+]{This-is-a+test} % Count the number of - and + in the string (3)
\countsep[- +]{T+h+i+s is{-a-}test} % Count the number of -, space and + in the string (6)
\end{document}

여담: 이것은 각 목록 요소에 대한 공백과 그룹을 확인해야 하기 때문에 특별히 빠르지는 않습니다. 따라서 etl@StevenB.Segletes의 솔루션보다 백그라운드에서 훨씬 더 많은 작업을 수행합니다. 이는 실제로 다음을 수행하려는 경우에만 필요합니다. 공백을 계산하거나 그룹으로 반복합니다.

관련 정보