Separate text by space except within quotation marks

6

I'm trying to use a regex to separate space-separated texts, except for those within quotation marks, for example:

Entrada: texto1 texto2 "texto3 texto4" texto5
Saida: Array("texto1", "texto2", "texto3 texto4", "texto5" );


Entrada: "texto0 texto1 texto2" texto3 "texto4"
Saida: Array("texto0 texto1 texto2", "texto3", "texto4" );


Entrada: "texto0 texto1" texto2
Saida: Array("texto0 texto1", "texto2");

Entrada: texto0 texto1 "texto2 texto3"
Saida: Array("texto0", "texto1", "texto2 texto3");
    
asked by anonymous 05.03.2018 / 18:50

4 answers

16

You can use this regex:

/".*?"|\w+/g

Explanation:

".*?" → seleciona o que estiver entre aspas duplas (inclusive as aspas)
|     → "ou"
\w+   → seleciona caractere alfanumérico (inclusive o underscore)
        e "soma" com os "próximos"
/g    → flag que seleciona todas as ocorrências

As the quotation marks are also selected, use .map() with replace to exclude the remaining double quotation marks:

entrada.match(/".*?"|\w+/g).map(function(e){ return e.replace(/"/g,''); });

Examples:

entrada1 = 'texto1 texto2 "texto3 texto4" texto5';
entrada2 = '"texto0 texto1 texto2" texto3 "texto4"';
entrada3 = '"texto0 texto1" texto2';
entrada4 = 'texto0 texto1 "texto2 texto3"';

saida1 = entrada1.match(/".*?"|\w+/g).map(function(e){ return e.replace(/"/g,''); });
saida2 = entrada2.match(/".*?"|\w+/g).map(function(e){ return e.replace(/"/g,''); });
saida3 = entrada3.match(/".*?"|\w+/g).map(function(e){ return e.replace(/"/g,''); });
saida4 = entrada4.match(/".*?"|\w+/g).map(function(e){ return e.replace(/"/g,''); });

console.log(saida1);
console.log(saida2);
console.log(saida3);
console.log(saida4);
    
05.03.2018 / 19:34
1

Try this, using look a head.

(?<=")[\w\s]+(?=")\b|\w+

link

Example of the js code executed by the link above:

    const regex = /(?<=")[\w\s]+(?=")\b|\w+/g;
const str = '"texto0 texto1 texto2" texto3 "texto4"

texto1 texto2 "texto3 texto4" texto5

"texto0 texto1 texto2" texto3 "texto4"

"texto0 texto1" texto2

texto0 texto1 "texto2 texto3"';
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }

    // The result can be accessed through the 'm'-variable.
    m.forEach((match, groupIndex) => {
        console.log('Found match, group ${groupIndex}: ${match}');
    });
}
    
05.03.2018 / 19:36
0

I think this may also solve the problem:

((\w+)|("[\w\s]+"))
    
05.03.2018 / 19:49
-1

The REGEX you are looking for is this:

[^\s"']+|"([^"])"|'([^'])'

    
05.03.2018 / 19:19