4

I am trying to extract parts of a string using regular expressions.

For example, from a string input John Smith (role: proof reader) I would like to extract John Smith and proof reader.

Here's my attempt

\ExplSyntaxOn

\seq_new:N \l_foo_seq

\regex_extract_once:nnN { ([\w\s]+)\(role:\s*([\w\s]+)\) } { {John Smith (role: proof reader)} } \l_foo_seq 

\newcommand{\showme}{
    \seq_map_inline:Nn \l_foo_seq {
        {##1,} \par
    }
}
\ExplSyntaxOff

The information I want is identified but the spaces are being removed. The output of \showme is

JohnSmith(role:proofreader),
JohnSmith,
proofreader,

I noticed that I can take the space-matching out of my regex and nothing changes, i.e.: ([\w]+)\(role:([\w]+)\). So, I guess the spaces are removed before \regex_extract_once:nnN does its stuff. I hoped that the enclosing braces would have presented the string as a single token with the spaces intact.

I'm a beginner at this. Advice and explanation would be welcome, as I'm finding the docs a bit hard to get into.

1
  • You shouldn't use \l_foo_seq. I don't know whether foo is the module name or the description, but it is missing the other one.
    – cfr
    Commented Jun 16 at 2:12

1 Answer 1

7

Spaces within the \ExplSyntax ... \ExplSyntaxOff "environment" are ignored. If you need an explicit space, you need to use ~. So the example code you give works if we replaces the spaces with ~. But in practice you would probably want the command to be part of a macro used in the document, in which case the spaces will be preserved as you expect:

Edit: Following up on cfr's comment, I've changed your sequence name to conform to the recommended Expl3 naming conventions, adding username as a substitute for the module part of the naming convention.

\documentclass{article}
\ExplSyntaxOn

\seq_new:N \l_blair_foo_seq
\regex_extract_once:nnN { ([\w\s]+)\(role:\s*([\w\s]+)\) } { {John~Smith~(role:~proof~reader)} } \l_blair_foo_seq 

\NewDocumentCommand{\extract}{m} {
\regex_extract_once:nnN { ([\w\s]+)\(role:\s*([\w\s]+)\) } {#1}  \l_blair_foo_seq }

\newcommand{\showme}{
    \seq_map_inline:Nn \l_blair_foo_seq {
        {##1,} \par
    }
}
\ExplSyntaxOff
\begin{document}
\showme
\extract{John Smith (role: proof reader)}
\showme
\end{document}

output of code

2
  • It shouldn't really be \l_foo_seq, though.
    – cfr
    Commented Jun 16 at 2:14
  • 2
    @cfr Good point. I've updated the answer.
    – Alan Munn
    Commented Jun 16 at 2:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .