A maior parte de um regex casa caracteres. Âncoras são diferentes: elas casam uma posição entre caracteres, e não consomem nada. É isso que permite dizer "no início da linha" ou "na borda de uma palavra" em vez de apenas "em algum lugar".
As âncoras comuns
^casa o início da string, e$casa o fim.^abc$casa apenas a string exataabc, nãoxabcx. Sem elas, um padrão pode casar qualquer substring, que é a causa mais comum de um regex casar mais do que o pretendido.\bcasa um limite de palavra, a posição entre um caractere de palavra e um caractere que não é de palavra (ou o início ou o fim da string).\bcat\bcasacatcomo palavra inteira, mas não ocatdentro decategory.\Bé o oposto: uma posição que não é um limite de palavra.- Alguns dialetos também oferecem
\Ae\zpara o início e o fim absolutos da string, que passam a importar quando o modo multilinha entra em cena.
Multilinha muda o que ^ e $ significam
Por padrão ^ e $ ancoram na string inteira. Ligue o modo multilinha (a flag m) e eles ancoram no início e no fim de cada linha, casando em cada quebra de linha. É isso que você quer ao varrer um bloco de texto linha a linha, e uma surpresa quando você não esperava, porque um padrão que casava uma vez agora casa em cada linha.
Onde elas mordem
Dois erros se repetem. Primeiro, colocar ^ ou $ no meio de um padrão por acidente, o que só pode casar em uma borda de linha e por isso normalmente não casa nada. Segundo, presumir que \b entende o seu alfabeto: em muitos motores, um caractere de palavra é só ASCII, então \b cai no lugar errado em torno de letras acentuadas ou outros scripts, a menos que você habilite o modo Unicode. Quando um casamento de "palavra inteira" se comporta de forma estranha com texto que não é inglês, a definição de limite de palavra é a primeira coisa a verificar.