javascript - js regular expression "/(\s|\uFEFF|\xA0)+$/" makes firefox and chrome busy -


when try call function of crossui(a js framework) rtrim text contents of dom grep jquery, firefox , chrome run busy. found regular expression in source code blocks browser. tried /[\s\ufeff\xa0]+$/ , works. why /(\s|\ufeff|\xa0)+$/ stuck? what's internal different between them?

$('body').text().replace(/(\s|\ufeff|\xa0)+$/, "");  alert('pass');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>  <div>      <div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>      <div>a</div>  </div>

a character set /[aa]/ equivalent /[a]/: set, assumed every element can appear once (and ones ignored). works okay since each option 1 character - there no space complications arise.

however, in case of failure, alternation /(a|a)/ needs check every branch, in case, because can't guarantee decision of 1 branch on won't have consequences. alternation not guarantee fixed width, not guarantee invariance of capture groups etc. in case, yes, both branches same; regexp engine doesn't check this.

thus, if have /[aa]+$/ , checking aaaax, have 4 checks, 1 each character, before match fails due non-end-of-stringness -- same /[a]+$/ (and in fact same /a+$/). /(a|a)+$/, have 2 * (1 + 2 * (1 + 2 * (1 + 2))) checks, thirty in total, each of branches gets checked. each additional a in string, time doubles, since engine needs check both a branch , a branch (!) see if 1 of them, miraculously, manages match.

so apply problem. said in comments, have \xa0 in 1 branch, , implicitly present in \s; /(\s|\ufeff|\xa0)+$/ double execution time on each , every &nbsp; have in white-space sequence not @ end of string. (the actual rtrim part, 1 replaced, not pose problem - end of string white-space sequence done without delay, first tested branch, 1 \s, succeeds , not backtrack.)


Comments