GREP styles can change form, not substance: they can apply formatting, but can’t change the text itself. You suggested what would seem the most appropriate approach: use a word list to fix case after the change to sentence case. The very rudimentary script below does just that.
To use the script, open the word list that has all words in their correct case (PetSmart, InDesign, NATO, RSPB), each word on a new line. Then open the document that needs to be treated and change its content’s case to sentence case. Make sure that the text and the list are the only two open documents and that the text is the active document. Then run the script.
The script reads the list, then looks in the text for the lower-case instance of each list item, case-insensitive (?i) and whole word only (). Case-insensitive searches are needed because sentence case may have rendered unfindable words at the beginning of sentences, such as Nato and Indesign.
As I said, it’s rudimentary but the basics are there and it can be refined in all kinds of ways.
(function(){
app.findGrepPreferences = app.changeGrepPreferences = null;
var list = app.documents[1].pages[0].textFrames[0].parentStory.contents.split('\r');
for (var i = 0; i < list.length; i++) {
app.findGrepPreferences.findWhat = '(?i)b' + list[i].toLowerCase() + 'b';
app.changeGrepPreferences.changeTo = list[i];
app.documents[0].changeGrep();
}
}());
Peter