en suivant l'idée de Mijoja, et en m'inspirant des problèmes exposés par JasonS, j'ai eu cette idée; J'ai vérifié un peu mais je ne suis pas sûr de moi, donc une vérification par quelqu'un de plus expert que moi dans js regex serait géniale :)
var re = /(?=(..|^.?)(ll))/g
// matches empty string position
// whenever this position is followed by
// a string of length equal or inferior (in case of "^")
// to "lookbehind" value
// + actual value we would want to match
, str = "Fall ball bill balll llama"
, str_done = str
, len_difference = 0
, doer = function (where_in_str, to_replace)
{
str_done = str_done.slice(0, where_in_str + len_difference)
+ "[match]"
+ str_done.slice(where_in_str + len_difference + to_replace.length)
len_difference = str_done.length - str.length
/* if str smaller:
len_difference will be positive
else will be negative
*/
} /* the actual function that would do whatever we want to do
with the matches;
this above is only an example from Jason's */
/* function input of .replace(),
only there to test the value of $behind
and if negative, call doer() with interesting parameters */
, checker = function ($match, $behind, $after, $where, $str)
{
if ($behind !== "ba")
doer
(
$where + $behind.length
, $after
/* one will choose the interesting arguments
to give to the doer, it's only an example */
)
return $match // empty string anyhow, but well
}
str.replace(re, checker)
console.log(str_done)
ma sortie personnelle:
Fa[match] ball bi[match] bal[match] [match]ama
le principe est d'appeler checker
à chaque point de la chaîne entre deux caractères quelconques, chaque fois que cette position est le point de départ de:
--- toute sous-chaîne de la taille de ce qui n'est pas voulu (ici 'ba'
, donc ..
) (si cette taille est connue; sinon, cela doit être plus difficile à faire peut-être)
--- --- ou plus petit que cela si c'est le début de la chaîne: ^.?
et, à la suite de cela,
--- ce qui doit être réellement recherché (ici 'll'
).
A chaque appel de checker
, il y aura un test pour vérifier si la valeur avant ll
n'est pas ce que nous ne voulons pas ( !== 'ba'
); si c'est le cas, nous appelons une autre fonction, et ce sera celle-ci ( doer
) qui fera les changements sur str, si le but est celui-ci, ou plus génériquement, qui entrera en entrée les données nécessaires pour traiter manuellement les résultats de la numérisation de str
.
ici nous changeons la chaîne donc nous devions garder une trace de la différence de longueur afin de décaler les emplacements donnés par replace
, tous calculés sur str
, qui lui-même ne change jamais.
puisque les chaînes primitives sont immuables, nous aurions pu utiliser la variable str
pour stocker le résultat de toute l'opération, mais j'ai pensé que l'exemple, déjà compliqué par les remplacements, serait plus clair avec une autre variable ( str_done
).
Je suppose qu'en termes de performances, cela doit être assez dur: tous ces remplacements inutiles de `` into '', this str.length-1
temps, plus ici le remplacement manuel par un exécutant, ce qui signifie beaucoup de tranchage ... probablement dans ce cas spécifique ci-dessus qui pourrait être regroupés, en coupant la corde une seule fois en morceaux autour de l'endroit où nous voulons l'insérer [match]
et .join()
en la coupant avec [match]
elle-même.
l'autre chose est que je ne sais pas comment il traiterait des cas plus complexes, c'est-à-dire des valeurs complexes pour le faux regard en arrière ... la longueur étant peut-être les données les plus problématiques à obtenir.
et, dans le checker
cas de multiples possibilités de valeurs non désirées pour $ behind, nous devrons faire un test dessus avec encore une autre regex (il est préférable d'être mis en cache (créé) à l'extérieur checker
, pour éviter que le même objet regex ne soit créé à chaque appel pour checker
) savoir si c'est ce que nous cherchons à éviter ou non.
j'espère avoir été clair; sinon n'hésitez pas, j'essaierai mieux. :)