我想操纵字符串。
以下hello_en.txt
应该变成hello
。
这与以下内容相关,并且很可能是重复的,命令与 StrBefore 功能相同,但可扩展。然而那里的问题并没有真正解决我的问题。
例子
我尝试\expandafter
在第一个 之前放置一个\StrBefore
,但没有作用。
\documentclass{article}
\usepackage{fontspec}
\usepackage{xstring}
\newcommand\mystring{hello\_en.txt}
\begin{document}
\StrBefore{\StrBefore{\mystring{}}{.}}{\_} % more complex DOES NOT WORK
\StrBefore{\StrBefore{hello\_en.txt}{.}}{\_} % simpler DOES NOT WORK
\end{document}
答案1
您必须使用可扩展的东西,但事实\StrBefore
并非如此,而且还要注意扩展的次数。
\documentclass{article}
\usepackage{xstring}
\newcommand\mystring{hello\_en.txt}
\begin{document}
\expandarg
\StrBefore{\mystring}{.}[\temp]
\StrBefore{\temp}{\noexpand\_}
\end{document}
的默认值为xstring
,\fullexpandarg
将被中和,因为\_
在这些情况下人们并不希望完全展开。
如果你尝试\edef\tmp{\_}
,你会得到替换文本,
\protect\global\let\\textunderscore\unhbox\voidb@x\kern .06em\vbox{\hrule width.3em}\\textunderscore
或者,如果你有\usepackage[T1]{fontenc}
,
\protect\T1\textunderscore
所以在这两种情况下,这都不是您想要\StrBefore
寻找的。
答案2
看起来像一份工作l3regex
大部头书
\documentclass{article}
\usepackage{l3regex}
\ExplSyntaxOn
\cs_new_eq:NN \regexreplace \regex_replace_all:nnN
\ExplSyntaxOff
\newcommand\mystring{hello\_en.txt}
\begin{document}
\regexreplace{\c{_}.*}{}\mystring
\show\mystring
\end{document}
(在正则表达式中,\c{_}
是完全匹配的控制序列\_
,而.*
是“任何字符”的标准正则表达式语法。)
答案3
一个解决方案stringstrings
。
\documentclass{article}
\usepackage{stringstrings}
\newcounter{tmpctr}
\newcommand\preunderscore[1]{%
\whereischar[q]{#1}{_}%
\setcounter{tmpctr}{\theresult}%
\addtocounter{tmpctr}{-1}%
\substring{#1}{1}{\thetmpctr}%
}
\begin{document}
\def\mystring{hello_en.txt}
\preunderscore{\mystring} is the truncated text.
\end{document}
@
如果想要用带引号的下划线指定名称,则需要进行一些小小的更改(假设文件名中没有字符):
\documentclass{article}
\usepackage{stringstrings}
\newcounter{tmpctr}
\newcommand\preunderscore[1]{%
\convertchar[q]{#1}{\_}{@}%
\whereischar[q]{\thestring}{@}%
\setcounter{tmpctr}{\theresult}%
\substring{#1}{1}{\numexpr\thetmpctr-1}%
}
\begin{document}
\def\mystring{hello\_en.txt}
\preunderscore{\mystring} is the truncated text.
\end{document}