4

Input: "string&number one&two" & "word&number two&three".

Desired output: "string number one two" & "word number two three".

In other words, the regexp has to match & only in quoted phrases and remain between them. I managed to do only the following:

(?<=^|\s").*?([&])[^"]+

But there is a non-greedy expression that matches only the first & in every phrase, if I use a greedy regex, it will match only the last & in the entire string.

How should I do that? I've really tried a lot of ways and lost my patience.

dda
  • 6,030
  • 2
  • 25
  • 34
  • Could the ampersands inside the quotes ever have spaces around them? – Gary_W Feb 25 '16 at 15:03
  • Gary_W - Actually I simplified task, there could be whole group of characters in any order, so answer is yes. – Dmitrii Petrov Feb 25 '16 at 15:35
  • You should state that then in your specs, in order to get a more complete answer that would handle the conditions you need to handle. – Gary_W Feb 25 '16 at 15:59

5 Answers5

2

Try this one. It works not only for two parts.

var str = '"string&number one&two" & "word&number two&three" & "string regex&test"';
str.replace(/&(?=[^"]+?\S")/g,' ');
console.log(str); 
// '"string number one two" & "word number two three" & "string regex test"'
Adam
  • 4,985
  • 2
  • 29
  • 61
1

The & signs between quotes would have an uneven amount of " ahead.

"string&number one&two" & "word&number two&three"
       3 " ahead -> uneven -> inside
                  3 " ahead -> uneven -> inside
                        2 " ahead -> even -> outside
                               1 " ahead -> uneven -> inside
                                          1 " ahead -> uneven -> inside

A lookahead can check at each & if there is not an even amount of " ahead until $ end.

&(?!(?:[^"]*"[^"]*")*[^"]*$)

See demo and more explanation at regex101

Community
  • 1
  • 1
bobble bubble
  • 16,888
  • 3
  • 27
  • 46
0

Do the following replace call;

var str = '"string&number one&two" & "word&number two&three"';
var result = str.replace(/(\S)&(\S)/g, "$1 $2");
console.log(result);

resulting string;

"string number one two" & "word number two three"

I have given javascript code here, but you can use similar functions from other languages.

buræquete
  • 14,226
  • 4
  • 44
  • 89
  • This will also replace the `&` outside `" "` if there is anything but spaces before and after it. `'"string&number one&two" string&number "word&number two&three"'` the one outside the `" "` will also get replaced in this case. – slugo Feb 25 '16 at 15:05
  • I tried to fit into the conditions he gave, it mentions there are quoted strings concatenated with &. Inner &'s are abutting the words around it, thus my regex. I can add further constraints to fit into quotations, but seems a bit of overdoing it. If he mentions of such cases, let's talk about it. – buræquete Feb 25 '16 at 15:06
  • @user1858268 - Good lesson in requirements gathering! Don't start coding until you have all the answers else you will be doomed to rework constantly. Most times the requester won't even be aware of the possibilities until you ask: Could there be spaces around the ampersands within the quotes? Could there be more than 2 sets of quoted text? Could there be ampersands outside of the quotes? Could the quoted text come from a text box and maybe contain a carriage return? etc, etc. Get all the specs spelled out up front and save yourself rework later and deliver a solid product the first time. – Gary_W Feb 25 '16 at 15:17
0

For the fun of it, here is bureaquete's solution in Oracle:

with tbl(str) as (
  select '"string&number one&two" & "word&number two&three"' from dual
)
select regexp_replace(str, '(\S)&(\S)', '\1 \2') fixed_string
from tbl;

Of course if the ampersands inside the quotes can have spaces around them, this solution fails, but that is not the requirement as given.

Gary_W
  • 9,933
  • 1
  • 22
  • 40
-1

You can't do it with just a regex. You will need to write some code that looks for a string between quotes, replace & with a space, and move on.

dda
  • 6,030
  • 2
  • 25
  • 34