4

I'm trying to create a table with two columns, in which the second one is representing lots of regular expression with all the character you could imagine. I tried with \verb|text| command, but it gets stuck when there are '%' symbols and, if i try to escape them with a backslash, works but it compares in the result as '...\%...'. There is any solution that can help me escape ALL characters?

This is a snippet of my code

\begin{table}[H]
\centering
\begin{tabularx}{\textwidth}{cX}
    \toprule
    $Placeholder$&$Regular~Expression$\\ 
    \midrule
    URL&(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)\\
    \bottomrule
\end{tabularx}
\caption{Regular Expressions}
\label{regex}\end{table}

UPDATE

Thank you for this workaround, works as expected! The reason why I used tabularx instead of tabular environment was because I had the necessity to manually break lines into the Regular Expression cell; with this solution seems to be still not possible, but better than nothing :)

  • 2
    I would just use a normal tabular with p{some length} instead of X and then you can use \verb – David Carlisle Feb 18 '16 at 21:52
3

As @DavidCarlisle has already indicated in a comment, you could proceed as follows: Use a tabular environment instead of a tabularx environment, use the p column type for the second column, and calculate its width using information about the width of the first column. This setup would allow the use the \url macro to typeset the long regexp string as if it were a URL string.

In the example below, using { and/or } is permissible because even though these characters occur in the regex string, they occur in the right order and are balanced. If this weren't the case, i.e., if the curly braces were unbalanced, one would have to use a character that doesn't occur anywhere in the regex string; e.g., \url!...! and \url M...M would both work since neither ! nor M occur in the regex string.

enter image description here

\documentclass{article}
\usepackage{booktabs}
\usepackage[spaces,hyphens]{url}

\newlength\lengtha
\newlength\lengthb
% Choose longest string in column A to calculate width
\settowidth{\lengtha}{\emph{Placeholder}}     
% Calculate width of column B as a residual
\setlength\lengthb{\dimexpr\textwidth-2\tabcolsep-\lengtha\relax} 

\begin{document}
\begin{table}
\begin{tabular}{@{} l p{\lengthb} @{}}
    \toprule
    \emph{Placeholder}&\emph{Regular~Expression}\\
    \midrule
    URL&  \url{(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)} \\
    \bottomrule
\end{tabular}
\caption{Regular Expressions}
\label{regex}\end{table}
\end{document}
| improve this answer | |
  • \url will allow breaks at only special locations like /. – user4686 Feb 19 '16 at 13:58
  • if all non-letters are used, there is always the possibility to use a letter as delimiter, like say M. Contrarily to \verb, \url M...M works. (whereas \verb M...M thinks it must use a space as delimiter.) – user4686 Feb 19 '16 at 14:06
  • @jfbu - Indeed, the use of curly braces to delimit the regex string worked because even though { and } occur in the regex string, they are balanced and occur in the right order. For sure, \url!...! would have worked too, since ! isn't in the regex string. – Mico Feb 19 '16 at 14:34
1

Due to the fact that tabularx gathers its contents, direct use of \verb would not work. Besides \verb needs one character not in the text to capture. The \detokenize needs a balanced text.

Announcing to the world a capture verbatim macro

The idea is to capture arbitrary characters (assuming however the standard catcodes naturally, else one could set up a loop to set all catcodes) and put it in a macro (not possible with \verb). The syntax is :

\literalset\foo<SPACE>ARBITRARY CHARACTERS<END OF LINE>

Notice that the spaces in the input right before the <END OF LINE> will not be captured in macro \foo. The <SPACE> at the start is mandatory and is removed during processing. Spaces not at the very end of the literal input will be captured.

Code:

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[margin=.5cm]{geometry}
\usepackage{tabularx}

\makeatletter
% \literalset\foo<SPACE>ARBITRARY CHARACTERS<END OF LINE>
\def\literalset #1{% assumes standard \endlinechar
    \begingroup
    \def\x{#1}%
    \catcode`\^^M 2
    \let\do\@makeother
    \dospecials
    \afterassignment\literalset@i
    \toks0=\bgroup }%
\def\literalset@i 
   {\expandafter\xdef\x{\expandafter\@gobble\the\toks0}\endgroup}
\makeatother

\begin{document}


% I have added a space between \/)? and (www compared to original.

\literalset\foo (https?:\/\/)? (www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)\\
Hello, all is fine here ? I hope so.

\typeout{I AM HERE: \meaning\foo}

\meaning\foo

\begin{table}[htbp]
\centering
\begin{tabularx}{\textwidth}{cX}
    \hline
    Placeholder&Regular Expression\\ 
    \hline
    URL&\texttt{\foo}\\
    \hline
\end{tabularx}
\caption{Regular Expressions}
\label{regex}
\end{table}

\end{document}

Notice that the wrapping of very long sequence of such detokenized characters is another issue, one could add now a \printliteral command which would add breakpoints after each character.

Blockquote


Update to add the promised \printliteral command. See the code comments for explanation and context.

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
%\usepackage[margin=.5cm]{geometry}
\usepackage{tabularx}

\makeatletter
% \literalset\foo<SPACE>ARBITRARY CHARACTERS<END OF LINE>
\def\literalset #1{% assumes standard \endlinechar
    \begingroup
    \def\x{#1}%
    \catcode`\^^M 2
    \let\do\@makeother
    \dospecials
    \afterassignment\literalset@i
    \toks0=\bgroup }%
\def\literalset@i 
   {\expandafter\xdef\x{\expandafter\@gobble\the\toks0}\endgroup}
\makeatother

% TeX has no toggle to tell it to break long words (of random
% characters) automatically when reaching end of line: it goes
% to the right margin and beyond in absence of hyphens and
% spaces if confronted to a non-interrupted sequence of
% characters. And in a \texttt, breaking at hyphens is usually
% inihibited.

% Here is a very simple-minded macro which allows to print a
% \foo which has been declared by \literalset, with automatic
% breaks. More sophisticated treatment is possible (e.g. use
% of discretionaries to allow insertion of continuation
% symbols at breaks).

% We add a little stretch to avoid underfull/overfull boxes.

\makeatletter
\def\printliteral   #1{\expandafter\printliteral@i#1\relax }%
\def\printliteral@i #1{\if\relax #1\else\hskip\z@ \@plus .4\p@\relax
                       #1\expandafter\printliteral@i \fi}
\makeatother

\begin{document}


% I have added a space between \/)? and (www compared to original.

\literalset\foo (https?:\/\/)? (www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)\\
Hello, all is fine here ? I hope so.

\typeout{I AM HERE: \meaning\foo}

\printliteral{\meaning\foo}

\begin{table}[htbp]
\centering
%\begin{tabularx}{\textwidth}{c>{\raggedright\arraybackslash}X}
\begin{tabularx}{\textwidth}{cX}
    \hline
    Placeholder&Regular Expression\\ 
    \hline
    URL&\texttt{\printliteral\foo}\\
    \hline
\end{tabularx}
\caption{Regular Expressions}
\label{regex}
\end{table}
%\showoutput

\end{document}

Blockquote

| improve this answer | |
  • @Mico I know: this is why I used a big text width. But remove the \texttt and you will see it does break at the hyphens but that these are the only suitable break points for TeX confronted to text without (normal) spaces. I will add a \printliteral macro to my answer. – user4686 Feb 19 '16 at 13:16
  • @Mico I thought the \\ was part of \foo but it appears it was probably a tabular new line. Anyway, my foo may differ from the OP (and not be a regular regex at all) as I played a bit with it at some point. – user4686 Feb 19 '16 at 14:08

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.