javascript - Är det att föredra att använda metoder på RegExp-objekt eller String-objekt?
Det finns regex-matchningsmetoder på både RegExp-objekt och String-objekt i Javascript.
RegExp-objekt har metoderna
- kör
- test
String-objekt har metoderna
- match
- sök
Metoderna exec och match är mycket lika:
/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"]
och test och search är också mycket lika:
/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
Finns det en preferens för att använda metoderna på RegExp-objekt eller på String-objekt?
Svar #1
Främst personlig preferens
Detta är mestadels en personlig preferens, även om det finns en liten skillnad i kapabiliteter (se sista stycket för den skillnaden). Om du inte vill börja mäta prestanda och göra frågan till en fråga om prestanda, är det mestadels en personlig preferens.
Jag föredrar att göra:
string.match(/word/)
eftersom jag tycker att det får koden att läsas som mitt sinne tänker på operationen. Jag tar strängobjektet och letar efter ett särskilt reguljärt uttryck i det. Det verkar rimligt för mig att leta efter något i en sträng är en metod på strängobjektet. Detta läses för mig som:
object.action(tool)
vilket är hur objektorienterad kod bör fungera enligt min åsikt.
Om du har:
/word/.match(string)
då känns det för mig som:
tool.action(object)
vilket jag tycker är mycket mindre logiskt och mindre objektorienterat. Ja, /word/ är tekniskt sett också ett objekt, men det är inte det objekt jag försöker arbeta med, jag ser det mer som ett verktyg eller en parameter jag använder med mitt objekt.
Uppenbarligen fungerar båda. Du kan själv avgöra vilken du gillar.
En stor skillnad
Det finns några saker som jag tror att du bara kan göra på ett reguljärt uttrycksobjekt. Till exempel, om du vill matcha alla förekomster av ett reguljärt uttryck, måste du skapa reguljära uttrycksobjektet, skicka det alternativet "g" och sedan kalla re.exec() flera gånger för att få varje matchning tills exec returnerar null som indikerar att det inte finns fler matchningar. Jag tror inte att du kan göra det med string.match().
Svar #2
Det finns några skillnader mellan match och exec när man använder global-flaggan g. Du kan inte loopa genom globala förekomster med match, medan med exec kan du:
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"]
Och index fungerar inte alls när man använder match med ett globaliserat RegExp-objekt:
var r=/b/g;
r.exec("0123b56b").index // 4
r.exec("0123b56b").index // 7
"0123b56b".match(r).index // undefined
"0123b56b".match(/b/).index // 4
