Substituting exact letter

I need to find and replace a letter, but it needs to be finished, it’s a music chord. Example: G I want to substitute for <b> G </ b>, this is ok, but there are times that can be like this: G / B and if you ask to replace it it will look like this: <b> G </ b> / B. How to differentiate G alone?

It depends a lot on the circumstances. You didn’t give enough data for us to be sure.

However, based on my understanding of tabulature and other writing of musical chords, you want it to match a G, even if there are more spaces and chords after, but not if it’s a “G over B”, indicated with a slash between.

Thus, my mental rule becomes, look for a G, followed by 0 or more spaces, as long as there isn’t a slash after that.

Thus, my search regex becomes: (G)(\h*)(?![/\h]) – this looks for a G and stores it in memory $1, and stores the 0-or-more spaces in memory $2, and makes sure that the character after the 0-or-more-spaces is not a / (and also not a space, because otherwise, it just makes the \h* shorter), but doesn’t store or gobble that character.

and my replace is <b> $1 </b>$2 – this replaces the match with your bold markup (I assume that’s what it is) around the matched G chord, followed by whatever spaces used to be there.

mode is regular expression, of course.

I made it easy to customize: if you want to change the chord you are searching for (like a Bb chord or F# chord), just change the G to something else; everything else in the regex is generic.

Based on your description, I think it’s what you want… but I could be wrong. If that’s not correct, please be more explicit, giving examples of when to change and when not to change, showing before and after examples

-----
FYI: I often add this to my response in regex threads, unless I am sure the original poster has seen it before. Here is some helpful information for finding out more about regular expressions, and for formatting posts in this forum (especially quoting data) so that we can fully understand what you’re trying to ask:

This forum is formatted using Markdown, with a help link buried on the little grey ? in the COMPOSE window/pane when writing your post. For more about how to use Markdown in this forum, please see @Scott-Sumner’s post in the “how to markdown code on this forum” topic, and my updates near the end. It is very important that you use these formatting tips – using single backtick marks around small snippets, and using code-quoting for pasting multiple lines from your example data files – because otherwise, the forum will change normal quotes ("") to curly “smart” quotes (“”), will change hyphens to dashes, will sometimes hide asterisks (or if your text is c:\folder\*.txt, it will show up as c:\folder*.txt, missing the backslash). If you want to clearly communicate your text data to us, you need to properly format it.

If you have further search-and-replace (“matching”, “marking”, “bookmarking”, regular expression, “regex”) needs, study this FAQ and the documentation it points to. Before asking a new regex question, understand that for future requests, many of us will expect you to show what data you have (exactly), what data you want (exactly), what regex you already tried (to show that you’re showing effort), why you thought that regex would work (to prove it wasn’t just something randomly typed), and what data you’re getting with an explanation of why that result is wrong. When you show that effort, you’ll see us bend over backward to get things working for you. If you need help formatting, see the paragraph above.

Please note that for all regex and related queries, it is best if you are explicit about what needs to match, and what shouldn’t match, and have multiple examples of both in your example dataset. Often, what shouldn’t match helps define the regular expression as much or more than what should match.

So I would modify my textual description of the rules, using C as the example this time instead of G: “Find a C, not followed by an alphanumeric, followed by any number of spaces (including zero), not followed by a slash or space.”

The regex just needs to be modified to exclude (but not capture or gobble) a “word character” (basically, alphanumeric) when looking for the C, using (?!\w)… which means the final Find what = (C(?!\w))(\h*)(?![/\h]). The replacement stays the same

If you have any more tweaks you’d like, please try reading some of the docs from the regex FAQ linked above, especially here. After reading that, try to make the modification yourself. If you cannot get it to work yourself, then show us how you modified the regex, and explain what you think it should be doing, and show us what it really does.

Here is a second search regex which contains two consecutive structures : a negativelook-ahead, followed with a positivelook-ahead, containing, itself, a nestednegativelook-ahead !

So, this regex only searches for the upper-caseC letter, but ONLY IF :

Not followed by a word character

AND

Followed with any range, even null, of horizontal blank characters

But ONLY IF that range is not followed, itself, by a / symbol

Note the interesting use of the possessive quantifier *+, after \h. As no backtracking process may occur, we’re sure that, after the blank characters matched zone, there will be, necessarily, a non blank character ;-))

As we just grab the C character, we can use the $0 syntax, which, simply, represents… … the C letter !

May be, it’s worth to point out that the regex engine working position, does NOT change, when evaluating any look-around structure ! So, regarding my regex version, this working location is :

Between the upper-case C and its next character, when evaluating the negative look-ahead (?!\w)

Still, between the upper-case C and its next character, when evaluating the positive look-ahead (?=\h*+.....)

And still, between the upper-case C and its next character, when evaluating the nested negative look-ahead (?=....(?!/)

For instance, if we consider the following regex :

(?-i)C(?!\w)(?=\h*+(?!/))\x20\x20#

It would match, for instance, the string “C #” ( with 2space chars between C and #). This means that, when the regex engine is about to evaluate the ending part of the regex \x20\x20#, its working location is, as expected, right after the C letter !

Now, after reflection and some tests, I thought about an other solution, using just 1 positive look-ahead :

SEARCH : (?x-i) C (?= \h++[^/] | [^\w\h/] )
REPLACE : <b> $0 </b>

Note that I used the free-spacing regex mode, (?x), in order to easily see the main parts of the regex ;-))

So, the regex engine searches for an upper-case CONLY IF , right after, there is :

A non-null range of horizontal blank characters, followed with a char, different from the / symbol ( => it can be an EOL char ! )

OR

A NON-word character, different from, both, an horizontal blank char and the / symbol