InDesign GREP Essentials: How to Add, Delete, and Re-Arrange Text
This article is part of a series of posts on using GREP in InDesign for beginners
One of the biggest advantages to using GREP with Find/Change in InDesign is the ability to manipulate the text you’ve found. For instance, you could find everything that fit the pattern of a price: \$\d+,*\d+\.\d{2} and then in the Change to field you could tell InDesign to put “Price: ” in front of that found text.
To do that, put the expression above in the Find what field. In the Change to field, enter Price: . Next, you have to tell InDesign to take the text it found with the expression and plop it right after the text you want to add. You can find what you need in the secret menu hiding under the @, under the Found sub-menu. Choose Found Text, or simply enter $0 (dollar sign zero). Now when you run the query, it’ll find everything that fits your price pattern and add Price: before it.
Using Subexpressions
By segmenting the expression into subexpressions you can manipulate those groups individually. For example, in a phone number, you may want to find ten digits, then offset each portion of the phone number by dots or dashes. Use subexpressions to break that long string of numbers into its three parts (area code, prefix, and line number). In InDesign, subexpressions are indicated by wrapping each up in a pair of parenthesis. So, to divide a 10-digit phone number, you would write the expression like this: (\d{3})(\d{3})(\d{4}). Each subexpression gets assigned a number, and in our example we have three, numbered left to right. You can have up to nine subexpressions in one GREP expression.
Let’s use those subexpressions to add dots between each segment of the phone number. Use the expression above to find any string of 10-digits in the Find what field. In the Change to field, use the secret menu to enter: Found (group) 1, then enter a dot (period), then Found 2, followed by a dot, followed by Found 3. The final expression would look like this: $1.$2.$3.
Note that in the Change to field, a period is stated as simply a period. When looking for a period in the Find field, you have to precede it with a backslash because a period is a wildcard for “any character”.
Deleting Content with GREP
If you wanted to drop off the area code in a phone number (perhaps they’re all the same) simply don’t “return” the group of found text that represents the area code (group 1 in our example). The Change to field would look like this: $2.$3.
Rearranging Content with GREP
You can also return groups in another order, which comes in handy for doing first name/last name reversals, for example. To do that, just reverse the order of the found items in the Change to field: $2$1
I would really like the grep find/change functionality to be possible to use inside a paragraph format. That way i could add text before reoccurring strings of text automatically.
I love your posts on grep, Erica. Event hough I don’t have that much use for grep in my day to day production flow, I am pretty sure knowing some basics will come in handy unexpectedly sometime.
Thanks! Yes, just having the basics down is good…and knowing IF something is possible, even if you have to reach out to others to find out the HOW to do it!
Erica, I agree: Basics are good! … Except when errors! ;-)
Read your text!!
(^/)
Here is a question that might form the basis for a later article. Is there a way in GREP to formulate a modestly complex find-but-not-find query? By that I mean to search for some string but exclude specific instances of that string based on some criteria?
One illustration would be to search for hyphens for conversion to n-dashes but not in a text string that starts with http, since hyphens inside a web address shouldn’t be changed. Or, in your example above, that’d mean looking for instances of number strings indicating prices that don’t already have “Price:” in front of them. Often, we need to fix inconsistencies in a text not correct universal deficiencies. If a change is already made, there’s no need to find it. That would save a lot of time.
And yeah, I guess for this “Price:” issue, we could follow up searching for “Price: Price:” and replacing that with just “Price:.” I have done those sorts of tricks before. But the more steps we have to make, the more likely we are to fail to make a critical one.
Mention of web addresses touches on one of my wishes for GREP enhancement. GREP was written for 1970s-era Unix-based computing. It needs to learn some new tricks that’d make dealing with weblinks and the Internet in general easier. Users should not have to cobble together some string of web address-finding code that works sometimes but not always. There should be ways to specify that a GREP search should:
1. Only search web addresses
2. Exclude all web addresses but include other text
3. Include web addresses with other text
Michael, you can do some exclusion by using a Negative LookAhead placed BEFORE you query.. Like so for excluding hyphen in http web address.
(?!(http).*-.*)-
But I agree a more easier approach would be useful.
Michael, you can do some exclusion by using a Negative LookAhead placed BEFORE you query.. Like so for excluding hyphen in http web address.
(?!http).*-.*)-
But I agree a more easier approach would be useful.
Sorry four the multiple post…
The GREP should be
(?!http.*-.*)-
I hope nobody will win $1,000,000,000.00 to lottery!
Not really sure too somebody could call someone with such a grep code!
A better use: “(?:…)”!
Be careful with Char styles!
That said, not really comments! = D
(^/)
Obi-wan, don’t forget this article is «part of a series of posts on using GREP in InDesign for beginners». For beginners is the important part here.
Thank you for mentioning that, JC! I think many people who want to dip their toes into the GREP waters get overwhelmed when we start throwing too many what-ifs and extreme expressions into the conversation. I want to convey to (mostly) designers that GREP is a handy thing to have in your skillset, at least a basic knowledge of what is possible with it. And that it’s not really scary and we don’t all have to know it all. Obi-wan, let’s keep the more in-depth discussions on the Treasures of GREP Facebook page, though. I don’t want GREP to seem any scarier than it is!
Erica, I only wanna tell you you forgot “\” in your code! =D … So, it’s not easy for beginners to follow you if the “basics” you try to learn them are wrong!! It’s not good for you and it’s not good for Grep!
Nothing else! ;-)
(^/)
For the record, Erica didn’t have any errors in her code. They were introduced when I copied and pasted the text from another source. My bad. Sorry for the confusion!
Aha! You’re right, JC! It’s for beginners! …
So, Erica could forget the points 1, 3 & 4! … But not really sure about the point 2! ;-)
(^/)
Since this is an article designed for beginners, I wonder if it would be possible to also include a breakdown of what the expression means, ie “slashD+ means to find any number of digits that fall between a dollar sign and a comma.”
I have been a beginner with GREP for at least two or three years now, and I still have trouble remembering what the different wildcard characters mean and how various elements (like LookAhead, etc.) work. Whenever I see or read a post about using GREP that includes an example of the GREP code, I try to figure out exactly what it means, so that I can try to think about how I might tweak it to solve specific problems I am facing.
Unfortunately, I am still in the phase where, more often than not, expressions that I rewrite or create from scratch don’t quite do what I want, and I don’t have enough knowledge to “debug” them. I hold out hopes that “translating” the GREP into English will help me be more successful with it over time.
Granted, this might make articles about GREP really unwieldy, but speaking as a beginner here, if you can add that explanation, I know it would help me immensely.
For the wildcards, you can always use the “magic menu” in InDesign (the @ symbol to the right of the expression box). I also have a cheatsheet on my site: https://www.ericagamet.com/wp-content/uploads/2016/04/Erica-Gamets-GREP-Cheat-Sheet.pdf
Peter Kahrel (wave hi to him in the comment below) has an excellent ebook from O’Reilly (GREP in InDesign) with a handy glossary.
Thanks for the reply. I just downloaded your cheatsheet, and am going to take a look at Peter Kahrel’s book as well.
I am pretty good at figuring out basic coding things (my dad was a programmer back in the 70s and he and I would sit together and create if/then flowcharts for fun), but for whatever reason, GREP seems to elude me even after using most of the resources listed on the GREP resources page here.
But, when it works, it is so much like magic that I keep coming back to it, and am bound and determined to become more effective at using it.
Thank you, this cheatsheet was invaluable!
Even today, it’s hard to find good resources for *genuine* beginners.
I’m glad the cheatsheet is still helping people out! We have a few videos on GREP on our YouTube channel, as well: youtube.com/creativepro
Hi Erica,
Nice post, as always. Just a small point of detail: if you want to add ‘Price: ‘ before dollar amounts, there’s no need to match those amounts precisely. All you need is the dollar sign followed by a digit:
Find what: \$\d
Change to: Price: $0
And if you do want match dollar amounts, there’s no need to try and match thousands, separators, decimals in order and precision: a dollar amount is a dollar sign followed by any of digit, comma, and/or dot:
Find what: \$\d[\d\.,]+
which is equivalent to your \$\d+,*\d+\.\d{2} but probably more designer-friendly :)
Melisa: the breakdown of that GREP expression is as follows (anything after // is a comment, not part of the code):
\$ // Match a dollar sign. $ in itself is a special symbol in GREP, the \ makes it into a literal
\\d // then match a digit
[\d\.\,] // Then match a digit (\d) dot (\.) or comma
+ // One or more times
In other words, \$\d looks for a dollar sign followed by a digit, [\d\.\,] forces InDesign match any digits, commas, and periods after that.
Michael: you can skip amounts that already have ‘Price: ‘ before them by using a so-called negative lookbehind:
Find what: (?
Hi Peter, just a comment to clarify:
If we want to catch each char here: 1,000.50\
What’s the more readable for beginners?
[\\0-9.,]
[0-9\\.,]
[0-9.,\\]
[\\\d\.\,]
[\d\\\.\,]
[\d\.\,\\]
[\\\d.,]
[\d\\.,]
[\d.,\\]
(^/) ;-)
I have to say, that when I wrote this article, I wrote it as one (way too long) article that brought complete newbies into the world of GREP. It has been broken into smaller chunks for clarity and not overwhelming those newbies. I introduce a couple of concepts with overly simplified expressions. So, while there are better more efficient ways to write the expressions, I wanted to over include information to make it visually easy to start seeing how the patterns work. For instance, showing someone that \d\d\d\d\d is how to find 5 digits makes visual sense. Later, we can inform them that \d{5} makes more sense.
But throwing all of the what ifs at them at the beginning is—I believe—what makes most designer’s heads spin. This has been my approach when I teach someone who is afraid of the expressions like those in the comments of the seasoned GREPpers. Baby steps. And I certainly didn’t expect Peter or Michel to even give this article a glance as it’s geared towards absolute beginners. Haha!
Angels will always be there to cherish another one!
;-)
Completely agree w/Erica, and I love the example of \d\d\d\d\d vs. \d{5}
We (at InDesignSecrets) get a TON of tech support questions emailed to us from new/beginning/occasional users, because they can’t find the answer here. We are purposely working on including posts aimed at these users in the blog, integrated wtih the more advanced/tricky/edge case ones that the InDesign geeks love. ;-)
Hi, Erica, thanks a lot for this post – extremely helpful, for beginners like me, anyway.
I have a question, though. It so happened that I lost all my custom GREPS, upgrading to Indesign CC, of which I was able to restore most, but one – which I need most ofthen.
I have texts where italics are marked as below:
_some text[Ital]
I can select the text alone with
(?<=\_).+(?=\[ital])
and change formatting, but to get rid of _ and [Ital] in the process in one step – I can't figure it out…
Can anyone help?
Try this:
Find what:
_(.+)\[Ital\]
Change to:
$1
Add any formatting needed in the Change format field.
Sorry, I meant: THANK YOU VERY MUCH, ERICA, worked like a charm:). You’re a life saver:)
THANK YOU VERY MUCH, worked like a charm:). You’re a life saver
I’m trying to find a grep expression that I thought would be pretty simple BUT I can’t seem to find the correct expression to bold all words at the beginning of each paragraph up to the EM Dash.
I also tried nested styles but found I’m unable to put the em dash character into the field.
A nested style is what you need. You should be able to put an em dash in the field that says “word” by default. If it won’t let you key it in, type one in the text of your document and copy it, then paste it into the field the nested style field.
Thanks Erica, I really appreciate you breaking it down for us beginners.
I’ve been poking around looking for a way to use a GREP find/replace as a nested GREP style inside a paragraph style… but this is seaming like an impossibility.
I’ve got data for business cards coming in from a spreadsheet via data merge, and I want to automatically remove text before a colon (it was there to give context to a multiple choice phone number list) but I obviously don’t want that on the card.
Right now I am using an “invisible” character style (no color, .1 size, 1% horizontal thanks to another suggestion on this website) but I was hoping there might be a more elegant way to simply remove the unwanted text on import. I guess I could do the find replace after performing the datamerg, but I was wanting to do it all as one step.
You’ve found the one major difference to Find/Change vs. GREP styles: the ability in the former to add to, delete, or re-arrange the found text. It’s a lot more flexible, but the changes have to be made manually (i.e. run each time you import or change the text). A GREP style only lets you find text and then apply a character style to that text (for the most part).
Alright I was afraid you would say something like that but i appreciate the confirmation. Now I just need to figure out the best way to make that change/find an easy part of my workflow! ;-)