我正在尝试遍历 CSV 文件,但遇到了麻烦。该文件有多行,我想逐项浏览 CSV 项。使用 etoolbox docsvlist 时,它会将换行符解释为空格。因此,我尝试通过用逗号替换空格字符来解决这个问题(并成功解决)。现在唯一的问题是 csv 迭代器将该命令解释为单个项。我相信这个问题与扩展有关,我尝试了许多 edef / expandafter 解决方案等,但都无济于事。
\documentclass[11pt,a4paper]{article}
\usepackage{etoolbox}
\usepackage{catchfile}
\usepackage{xstring}
\begin{document}
\CatchFileDef{\CSVdata}{FILE.csv}{}% Formatted CSV data
\newcommand{\CSVdataNoSpaces}{\StrSubstitute[0]{\CSVdata}{ }{,}}
\renewcommand{\do}[1]{#1\\}% new line in between items
\expandafter\docsvlist\expandafter{\CSVdataNoSpaces} % considers the command one csv item
\expandafter\docsvlist\expandafter{\CSVdata} % iterates thru, but spaces are problem
\end{document}
答案1
您定义\CSVdataNoSpaces
扩展为标记序列\StrSubstitute[0]{\CSVdata}{ }{,}
。
\expandafter
中的 -chain传递\expandafter\docsvlist\expandafter{\CSVdataNoSpaces}
了这个标记序列,因此你会得到类似的内容\docsvlist{\StrSubstitute[0]{\CSVdata}{ }{,}}
。
因此的参数\docsvlist
是标记序列\StrSubstitute[0]{\CSVdata}{ }{,}
。
标记序列\StrSubstitute[0]{\CSVdata}{ }{,}
不包含任何未嵌套在花括号中的逗号。因此,整个标记序列被视为 csv 列表/逗号分隔值列表的唯一元素。
但你很幸运:
\StrSubstitute
接受一个可选参数,表示一个控制序列标记,该标记将被(重新)定义为一个宏,该宏将作为顶级扩展提供形成结果的标记\StrSubstitute
。
因此你可以这样做\StrSubstitute[0]{\CSVdata}{ }{,}[\CSVdataNoSpaces]
:
\documentclass[11pt,a4paper]{article}
\usepackage{etoolbox}
\usepackage{catchfile}
\usepackage{xstring}
\begin{document}
\CatchFileDef{\CSVdata}{FILE.csv}{}% Formatted CSV data
% \expandarg % -> xstring-macros "hit" the 1st-token of arguments with \expandafter once before processing them further.
% \fullexpandarg % -> xstring-macros apply `\edef` to the arguments before processing them further.
% \noexpandarg % -> xstring-macros process arguments as is, without applying whatsoever expansion to them before processing them.
% \fullexpandarg is the default.
% See the xstring-manual for more information.
% If you wish \StrSubstitute to work on the result
% of expanding \CSVdata, you need \expandarg (->
% \StrSubstitute works on \CSVdata's toplevel-
% expansion) or \fullexpandarg (-> \StrSubstitute
% works on \CSVdata's full expansion/\edef-expansion) .
\StrSubstitute[0]{\CSVdata}{ }{,}[\CSVdataNoSpaces]%
\show\CSVdata
\show\CSVdataNoSpaces
\renewcommand{\do}[1]{#1\\}% new line in between items
\expandafter\docsvlist\expandafter{\CSVdataNoSpaces}% iterates thru, spaces are turned into commas which might be a problem with spaces placed into the file on purpose
\expandafter\docsvlist\expandafter{\CSVdata} % iterates thru, but spaces are problem
\end{document}
我建议采用一种不同的方法:
除了执行此\StrSubstitute
游戏之外,您可以“告诉”\CatchFileDef
在每个行尾后附加一个逗号而不是空格 - 这可能更安全,因为这样您就不会得到故意放入 .csv 文件中的空格:
\documentclass[11pt,a4paper]{article}
\usepackage{etoolbox}
\usepackage{catchfile}
\begin{document}
\CatchFileDef{\CSVdata}{FILE.csv}{\endlinechar=`\,}% Formatted CSV data
\show\CSVdata
\renewcommand{\do}[1]{#1\\}% new line in between items
\expandafter\docsvlist\expandafter{\CSVdata}% iterates thru.
\end{document}
根据 .csv 文件包含的数据,您可能会对 Nicola Talbot 博士的数据工具-包裹。