javascript - É preferível usar métodos em objetos RegExp ou em objetos String?


Existem métodos de correspondência de regex tanto em objetos RegExp como em objetos String em Javascript.

Os objetos RegExp têm os métodos

  • executar
  • teste

Os objetos String têm os métodos

  • partida
  • pesquisar

Os métodos exec e match são muito semelhantes:

/word/.exec("words");
//Result: ["word"]
"words".match(/word/);
//Result: ["word"]

/word/.exec("No match");
//Result: null
"No match".match(/word/);
//Result: null

/word/g.exec("word word");
//Result: ["word"]
"word word".match(/word/g);
//Result: ["word", "word"]

e o test e o search também são muito semelhantes:

/word/.test("words");
//Result: true
"words".search(/word/);
//Result: 0
//Which can converted to a boolean:
"word".search(/word/) > -1;
//Result: true

/word/.test("No match");
//Result: false
"No match".search(/word/) > -1;
//Result: false

Existe uma preferência por usar os métodos em objetos RegExp ou em objetos String?

Resposta #1

Principalmente preferência pessoal

Isto é principalmente uma preferência pessoal, embora haja uma ligeira diferença nas capacidades (veja o último parágrafo para essa diferença). A menos que queira começar a medir o desempenho e transformar a questão numa questão de desempenho, é principalmente uma preferência pessoal.

Prefiro fazer:

string.match(/word/)

porque acho que isso faz o código ler-se como o meu cérebro pensa a operação. Estou a pegar no objeto string e a procurar uma expressão regular particular nele. Faz sentido para mim que procurar algo numa string seja um método do objeto string. Isto lê-se para mim como:

object.action(tool)

que é como o código orientado a objetos deveria funcionar na minha opinião.

Se tiver:

/word/.match(string)

então para mim parece-se com:

tool.action(object)

que considero muito menos lógico e menos orientado a objetos. Sim, /word/ é tecnicamente um objeto também, mas não é o objeto sobre o qual estou a tentar operar; penso nele mais como uma ferramenta ou um parâmetro que estou a usar com o meu objeto.

Obviamente ambos funcionam. Podes decidir por ti mesmo qual gostas.

Uma Diferença Principal

Existem algumas coisas que acredito que só se podem fazer com um objeto de expressão regular. Por exemplo, se quiser corresponder todas as ocorrências de uma expressão regular, tem de criar o objeto de expressão regular, passar-lhe a opção "g" e depois chamar re.exec() várias vezes para obter cada correspondência até que exec devolva null, indicando que não há mais correspondências. Não penso que se possa fazer isso com string.match().

Resposta #2

Existem algumas diferenças entre match e exec ao usar a flag global g. Não se pode percorrer ocorrências globais com match, enquanto usando exec é possível:

var string="xabx xnnx";
var regexp=new RegExp('x([^x]*)x','g');

// match returns the list of matching parts:
string.match(regexp) // ["xabx", "xnnx"]

// with exec you could build a loop:
var match=regexp.exec(string);
while (match) {
    console.log(match);
    match=regexp.exec(string);
}
// This loops through matches and returns subpatterns too:
// ["xabx", "ab"]
// ["xnnx", "nn"]

E index não funciona de todo quando se usa match com um objeto RegExp globalizado:

var r=/b/g;
r.exec("0123b56b").index // 4
r.exec("0123b56b").index // 7
"0123b56b".match(r).index // undefined
"0123b56b".match(/b/).index // 4