Skip to main content
Inspiring
August 11, 2020
Answered

Grep question

  • August 11, 2020
  • 2 replies
  • 2137 views

I was working through Peter Kahrel's Grep In InDesign book but am stumped. Let's say I'm trying to change cat to dog but honour the case of the first letter of the word. 

 

FIND: (?!)cat(?=[s \.,])

REPLACE: dog

 

Shouldn't that replace cat with dog and Cat with Dog? Doesn't for me at least. The only difference I can see between the version in the book and mine is that I've include a positive lookahead.

 

If this isn't the place to ask about Greps in InDesign please let me know where is, I do want to post questions to the appropriate place. 

This topic has been closed for replies.
Correct answer Peter Kahrel

Reading back that passage, I have to admit that it suggests that the replacement works as you expected. But as Jongware points out, the case-insensitive specification in your GREP expression has no effect on the replacement expression. Some GREP flavours do work as you expected, but Adobe's doesn't.

 

So the quick answer to your query is 'No, you didn't get it wrong, you were misled.'

 

Thanks for pointing out the problem, I'll get it changed. In the meantime, as ever, we're lucky that InDesign is so well scriptable. Many, if not most, problems can be worked around with a script. Just for interest's sake I did the script below to fix the problem you mentioned. To use it, enter the find and change expressions, then run the script. It produces the reult you expected in the first place. (It targets the whole document.)

// Input from the dialog
replacementLowerCase = app.changeGrepPreferences.changeTo;
// Input with its first letter capitalised
replacementUpperCase = replacementLowerCase.replace (/^(.)/, function () {
  return arguments[0].toUpperCase();
});

found = app.documents[0].findGrep();
for (i = found.length-1; i >= 0; i--) {
  firstChar = found[i].characters[0].contents;
  // If the found word's first character is upper-case
  // use the upper-cased variant of the replacement
  if (firstChar === firstChar.toUpperCase()) {
    found[i].contents = replacementUpperCase;
  } else {
    found[i].contents = replacementLowerCase;
  }
}

Peter

2 replies

Peter Kahrel
Community Expert
Community Expert
September 7, 2020

This is as good a place as any to ask GREP-related questions, Zimbop. Most script writers know Grep and they know InDesign's Grep flavour. You could also try the general INdesign forum (where many script writers hang out anyway).

 

What you're after (case preservation) is possible in the Text tab, not in the Grep tab. InDesign's Grep can't be used to change case just like that, you need a script for that. You say that I claim in the book that you can preserve case -- could you point me to the page where I say that?

 

Another thing: What are you trying to achieve with (?!)? ?! is used for negative lookaheads, maybe you meant (?i) (for case-insensitive on).

 

P.

 

MrZZYAuthor
Inspiring
September 7, 2020

Hi Peter,

thanks, this was a while ago now, but I think this is the section that was I was referring to. You're absolutely right about the (?!) it was meant to be (?i), I'm not sure if that was what was stopping my GREP from working or just an error when typing up the forum post.

 

p.42

The words that should be replaced are given as a list of alternatives separated by the vertical bar, and each alternative is replaced with figure. GREP is case-sensitive by default; to replace case-insensitively, it is necessary to add (?i) before the expression. This will replace chart with figure and Chart with Figure.

Peter Kahrel
Community Expert
Peter KahrelCommunity ExpertCorrect answer
Community Expert
September 7, 2020

Reading back that passage, I have to admit that it suggests that the replacement works as you expected. But as Jongware points out, the case-insensitive specification in your GREP expression has no effect on the replacement expression. Some GREP flavours do work as you expected, but Adobe's doesn't.

 

So the quick answer to your query is 'No, you didn't get it wrong, you were misled.'

 

Thanks for pointing out the problem, I'll get it changed. In the meantime, as ever, we're lucky that InDesign is so well scriptable. Many, if not most, problems can be worked around with a script. Just for interest's sake I did the script below to fix the problem you mentioned. To use it, enter the find and change expressions, then run the script. It produces the reult you expected in the first place. (It targets the whole document.)

// Input from the dialog
replacementLowerCase = app.changeGrepPreferences.changeTo;
// Input with its first letter capitalised
replacementUpperCase = replacementLowerCase.replace (/^(.)/, function () {
  return arguments[0].toUpperCase();
});

found = app.documents[0].findGrep();
for (i = found.length-1; i >= 0; i--) {
  firstChar = found[i].characters[0].contents;
  // If the found word's first character is upper-case
  // use the upper-cased variant of the replacement
  if (firstChar === firstChar.toUpperCase()) {
    found[i].contents = replacementUpperCase;
  } else {
    found[i].contents = replacementLowerCase;
  }
}

Peter

Sunil Yadav
Legend
September 7, 2020

If you are not getting your solution for grep here, you may also put up grep question on https://stackoverflow.com/.

 

Sunil