Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
82 views
in Technique[技术] by (71.8m points)

How to use conditionals when replacing in Notepad++ via regex

Consider the following regex:

([a-zA-Z])([a-zA-Z]?)/([a-zA-Z])([a-zA-Z]?)

If the text is: a/b the capturing groups will be:

/1  'a'
/2  ''
/3  'b'
/4  ''

And if the text is: aa/b the capturing groups will be:

/1  'a'
/2  'a'
/3  'b'
/4  ''

Suppose, I want to find and replace this string in Notepad++ such that if /2 or /4 are empty (as in the first case above), I prepend c.

So, the text a/b becomes ca/cb. And the text aa/b becomes aa/cb

I use the following regex for replacing:

(?(2)12|01)/(?(4)34|03)

But Notepad++ is treating ? literally in this case, and not as a conditional identifier. Any idea what am I doing wrong?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The syntax in the conditional replacement is

(?{GROUP_MATCHED?}REPLACEMENT_IF_YES:REPLACEMENT_IF_NO)

The { and } are necessary to avoid ambiguity when you deal with groups higher than 9 and with named capture groups.

Since Notepad++ uses Boost-Extended Format String Syntax, see this Boost documentation:

The character ? begins a conditional expression, the general form is:

?Ntrue-expression:false-expression

where N is decimal digit.

If sub-expression N was matched, then true-expression is evaluated and sent to output, otherwise false-expression is evaluated and sent to output.

You will normally need to surround a conditional-expression with parenthesis in order to prevent ambiguities.

For example, the format string (?1foo:bar) will replace each match found with foo if the sub-expression $1 was matched, and with bar otherwise.

For sub-expressions with an index greater than 9, or for access to named sub-expressions use:

?{INDEX}true-expression:false-expression

or

?{NAME}true-expression:false-expression

So, use ([a-zA-Z])([a-zA-Z])?/([a-zA-Z])([a-zA-Z])? and replace with (?{2}$1$2:c$1)/(?{4}$3$4:c$3).

The second problem is that you placed the ? quantifier inside the capturing group, making the pattern inside the group optional, but not the whole group. That made the group always "participating in the match", and the condition would be always "true" (always matched). ? should quantify the group.

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...