Hello, @anos, @terry-r, @alan-kilborn, @peterjones and All,
And here is my solution !
If we use the FREE-SPACING mode (?x), for the SEARCH part :
SEARCH (?x-s) (?: ( \+A (\*)? ) | ( \+B (\*)? ) | (2) ) (?!.*,)
Groups --> No 1 2 3 4 5 Look-Ahead
REPLACE (?1(?{2}1:a))(?3(?{4}2:b))?5X
BEWARE that, in the REPLACE part, the FREE-SPACING mode is FORBIDDEN. So, ONLY for INFO :
REPLACE ( ?1 ( ?{2} 1 : a ) ) ( ?3 ( ?{4} 2 : b ) ) ?5 X
and given the data :
12345-01, A+A*2B+B*+A
12345-02, A+AB+B*+AA
it would return :
12345-01, A1XB2a
12345-02, AaB2aA
Notes :
The first part (?x-s) of the regex search means that :
The free-spacing mode is set ( Spaces are not taken in account, except for the [ ] syntax or an escaped space char )
Due to (?-s) syntax, the dot regex symbol matches a single standard char only ( not an EOL char )
Then, the (?:......) syntax defines a non-capturing group
Now, in this non-capturing group, we have 3 alternatives and the first two contain an optional inner group (\*)? ( Remember that the ? is an other form of the {0,1} quantifier )
To end, all this regex , so far, will match ONLY IF the final negative look-ahead structure (?!.*,) is verified, that is to say if at current position, reached by the regex engine, there is never a comma, at any further position, in current line
Now, in the replacement regex :
The (?1(?{2}1:a)) syntax means that if group 1 exists, then if group 2 exists, then write 1 else write a
The (?3(?{4}2:b)) syntax means that if group 3 exists, then if group 4 exists, then write 2 else write b
Finally, the ?5X means that if group 5 exists, then write an X ( The parentheses are not mandatory as this part ends the regex
Note also that it’s not necessary to surround the groups 1, 3 and 5 with braces as these groups are not immediately followed with a digit !
Best Regards,
guy038