tags:

views:

172

answers:

3

In my LaTeX files, I have literally thousands of occurrences of the following construct:

$\displaystyle{...math goes here...}$

I'd like to replace these with

\mymath{...math goes here...}

Note that the $'s disappear, but the curly braces remain---if not for the trailing $, this would be a basic find-and-replace. If only I knew any regex, I'm sure it would handle this with no problem. What's the regex I need to make this happen?

Many thanks in advance.

Edit: Some issues and questions have arisen, so let me clarify:

  1. Yes, $\displaystyle{ ... }$ can occur multiple times on the same line.
  2. No, nested }$'s (such as $\displaystyle{...{more math}$...}$) cannot occur. I mean, I suppose it could if you put it in an \mbox or something, but I can't imagine why anyone would ever do that inside a $\displaystlye{}$ construct, the purpose of which is to display math inline with text. At any rate, it's not something I've ever done or am likely to do.
  3. I tried using the perl suggestion, but while the shell raised no objections, the files remained unaffected.
  4. I tried using the sed suggestion, but the shell objected to an "unexpected token near `('". I've never used sed before (and "man sed" was obtuse), but here's what I did: navigated to a directory containing .tex files and typed "sed s/\$\\displaystyle({[^}]+})\$/\\mymath\1/g *.tex". No luck. How do I use sed to do what I want?

Again, many many thanks for all offered help.

+4  A: 

sed:

s/\$\\displaystyle({[^}]+})\$/\\mymath\1/g
Ignacio Vazquez-Abrams
+1  A: 
perl -pi -e 's/$\\displaystyle({.*)}\$/\\mymath$1}/g' *.tex

if multiples }$ are on the same line you need a non greedy version:

perl -pi -e 's/$\\displaystyle({.*?)}\$/\\mymath$1}/g' *.tex
bertolami
Doesn't `{` need escaping in Perl? And because of the greedy `.*`, it''l match the first occurrence of `$\displaystyle{` and the last occurrence of `}$`: you sure that is correct? Take the line `... $\displaystyle{ foo }$ ... $\displaystyle{ bar }$ ...` for example.
Bart Kiers
seems not to be necessary within a regex. tried the above expression and worked.
bertolami
Ah, ok. I'm not really familiar with Perl, and in most regex implementations I know of, they do need escaping. Thanks for the info.
Bart Kiers
your are right if there are multiple }$ on the same line it does not work correctly. If this is required the following snipped should work perl -pi -e 's/$\\displaystyle({.*?)}\$/\\mymath$1}/g' *.tex
bertolami
Not to bust you b@lls or something, but what if the `$\displaystyle{` and `}$` are *not* on the same line? :)
Bart Kiers
:) perls regex is on line level. thus what you could do is to join the entire file on a single line e.g. with a specific line ending symbol, then executing the regex, and split the line again. but this doesn't fit directly in the -pi -e framework. what about sed? it works on line level, too?
bertolami
Yes, most regex implementations will *not* let the `.` match line breaks. You can enable the DOT-ALL flag (if the engine supports it) by adding `(?s)` at the start of the pattern (or at least before the `.`) to let it also match line breaks. If the `s` option is not implemented, something like `[\s\S]` will result in the same.
Bart Kiers
+3  A: 

Be very careful when using REGEX to do this type of substitution because the theoretical answer is that REGEX is incapable of matching this type of pattern.

REGEX is a finite state machine; it does not incorporate a pushdown stack so it cannot work with nested structures such as "{...math goes here...}" if there is any possibility of nesting such that something like "{more math}$" can appear as part of a "math goes here" string. You need at a minimum a context free grammar to describe this type of construct - a state machine just doesn't cut it!

Now having said that, you may still be able to pull this off using REGEX provided none of your "math goes here" strings are more complex than what a state machine can handle.

Give it a shot.... but beware of the results!

NealB
You could account up to a fixed number of nested `{...}`'s, although those regex are a pain to construct. Accounting for 2 nested brackets even makes me light-headed! Also note that some regex engines (.NET, PHP and Perl) have the capability to match their own pattern, or a prt of their own pattern (the *can* handle recursion). Most of the regex implementations simply cannot be called "regular" in a mathematical/strict sense. Nevertheless, using regex in this case may very well not be the best option here! +1
Bart Kiers
@NealB ;) your computer is a state machine, too, isn't it?. And I don't agree that regex isn't a good choice. in my opinion it is a very reasonable choice that can match 99% of the cases. the effort to parse the entire stuff is probably much higher than fixing the remaining 1%
bertolami
Note that Alex has "thousands" of these things to replace. In that case, identifying only 1% that *do* have nested `{...}`'s might be a pain in the bottom! :)
Bart Kiers