I have the following macro definition:

\tl_new:N \l_jdhao_hlx_tl
  \tl_replace_all:Nnn\l_jdhao_hlx_tl{\ }{~}%
  \tl_replace_all:Nnn\l_jdhao_hlx_tl{,}{,{\-}}% allow line breaking at a comma

The above does simple replacement, but I don't think that I can do some conditional replacement. For example, I'd like to be able to replace a hyphen that is preceeded and followed by an alphanumeric to be the same, except that the hyphen is replaced by \-/ (e.g., alpha-baker would be be changed to alpha\-/baker). At the same time where there is a hyphen that either has spaces or non-alphanumeric character will be left alone. Is this possible? What I'm looking to do is have a hyphen that will not cause hyphenation. I'm think that I can use \regex_replace_all instead of \tl-replace_all. Does this even make sense, or is there a better way?

Update #1

The version information displayed by pdflatex is:

pdfTeX 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian)
kpathsea version 6.1.1
Copyright 2013 Peter Breitenlohner (eTeX)/Han The Thanh (pdfTeX).
There is NO warranty.  Redistribution of this software is
covered by the terms of both the pdfTeX copyright and
the latest FNU general Public License.
For more information about these matters, see the file
named COPYING and the pdfTeX source.
Primary author of pdfTeX: Peter Breitenlohner (eTeX)/Han The Thanh (pdfTeX).
Compiled with libpng 1.2.49; using libpng 1.2.50
Compiled with zlib 1.2.8; using zlib 1.2.8
Compiled with poppler version 0.24.5

Update #2

I was able to get this working, to a degree, by adding \usepackage{regexpatch} and/or \usepackage{l3regex}. Now it runs but the output does not look like what you have below. I get the following:

The token list \l_jdb_tl contains the tokens:
> a (the letter a)
> l (the letter l)
> p (the letter p)
> h (the letter h)
> a (the letter a)
> \- (control sequence=macro:->\discretionary {-}{}{})
> / (the character /)
> b (the letter b)
> e (the letter e)
> t (the letter t)
> a (the letter a)
>recently read>}

I'm not sure why I get the > \- (control sequence=macro:->\discretionary {-}{}{}) and below is the control sequence=macro:->\x@protect \-\protect \- statement. The only real difference is that I move the regex_const into the regex_replace_all. Probably a difference of versions.

Final Update Hi all, I was able to finally get this all to work as I needed it to and it is better than I had holes. Just to close this off, here is the regex code I have that replaces the original code I documented:

  \regex_replace_all:NnN\c_jdhao_space_regex{\cS\ }\l_jdhao_hlx_tl

Now, it is relatively easy to expand upon the above and know that I can use patterns to make sure that replacement tokens are used under the right circumstances, where the old macros were just straight "find this string and replace it with this other one".

  • \regex_replace_all:nnN is slower than \tl_replace_all:Nnn, but can be used for this, yes. – Skillmon Jan 2 at 22:45
  • You get a different output because \- is defined differently in your project. – Skillmon Jan 4 at 9:42

A single regex replacing the case you explicitly mentioned in your question (alphanumeric followed by hyphen followed by alphanumeric replaced with the same alphanumeric characters and a \-/ in between).

I precompiled the regex with \regex_const:Nn, this should save some time if the regex is to be used several times. The code doesn't produce any printed output, only some console ouput:


\regex_const:Nn \c_jonbelanger_regex { ([A-Za-z\d])-([A-Za-z\d]) }
\tl_new:N \l_jonbelanger_tl
\NewDocumentCommand \hyphenthingy { m }
    \tl_set:Nn \l_jonbelanger_tl { #1 }
    \regex_replace_all:NnN \c_jonbelanger_regex { \1\c{-}/\2 } \l_jonbelanger_tl
    \tl_show_analysis:N \l_jonbelanger_tl


The following is printed to the console:

The token list \l_jonbelanger_tl contains the tokens:
>  a (the letter a)
>  l (the letter l)
>  p (the letter p)
>  h (the letter h)
>  a (the letter a)
>  \- (control sequence=macro:->\x@protect \-\protect \-  )
>  / (the character /)
>  b (the letter b)
>  a (the letter a)
>  k (the letter k)
>  e (the letter e)
>  r (the letter r).
  • This is exactly what I was hoping to get. This is fantastic. – JonBelanger Jan 3 at 14:03
  • OK, when I try to run this, I get an ! Undefined control sequence. error on the first \regex_const. – JonBelanger Jan 3 at 17:02
  • 1
    @JonBelanger \regex_const:Nn was introduced on 2017-05-26, so if your TeX distribution is older than that you should update it. – Skillmon Jan 3 at 18:27
  • For now I have to run on Ubuntu 14.04. Is there an updated version that I can use? Or is there an alternative to using \regex_const:Nn (maybe not precompile the expressions)? – JonBelanger Jan 3 at 19:28
  • @JonBelanger \regex_replace_all:nnN was introduced in the same version, so if your version is older than that you couldn't use it either way. You can use the vanilla TeXLive instead of your distribution's (that's what I'm doing with my Arch box). – Skillmon Jan 3 at 19:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.