PageRenderTime 68ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/flash/Shared/RegExp.as

https://bitbucket.org/theit8514/expfavmenu
ActionScript | 1262 lines | 1150 code | 4 blank | 108 comment | 68 complexity | 0831b78cd17969b11b346d1044bc053b MD5 | raw file
Possible License(s): BSD-3-Clause
  1. //---------------------------------------------------------------------------
  2. // RegExp object for Flash5 ActionScript Ver1.01
  3. //Author: Pavils Jurjans
  4. //Email : pavils@mailbox.riga.lv
  5. // Default source for this file can be found at:
  6. // http://www.jurjans.lv/flash/RegExp.html
  7. //and an interactive tester at http://www.jurjans.lv/flash/RegExp_test.html
  8. //---------------------------------------------------------------------------
  9. // This class is provided for flash community for free with a kind request
  10. // to keep the copyright lines in AS file untouched. However, debugging and
  11. // development of class takes much time limiting my opportunities to earn
  12. // some income on other projects. To overcome this, I have set up an account
  13. // with PayPal (http://www.paypal.com). Please, if you find my work valuable,
  14. // especially if you use it in commercial projects, make a donation
  15. // to pavils@mailbox.riga.lv of amount you feel is right. Please provide your
  16. // E-mail address upon payment submission so I can enlist you in my upgrade newslist.
  17. //---------------------------------------------------------------------------
  18. /** Based on RegExp object for Flash5 ActionScript Ver1.01<br/>
  19. *RegExp is defined in Javascript and Actionscript 3 but is missing in Actionscript 2 (see Actionscript 3 documentation).<br>
  20. *Test Regular Expressions at <a href='http://www.jurjans.lv/flash/RegExp_test.html'>http://www.jurjans.lv/flash/RegExp_test.html</a>.<br>
  21. *Read a nice summary of their use at <a href='http://www.websina.com/bugzero/kb/regexp.html'>http://www.websina.com/bugzero/kb/regexp.html</a><br>
  22. * Help Document Last Updated: Jan 11, 2010
  23. *@author Pavils Jurjans and Joey Lott with additions by the CLIPS team
  24. @email gpclarke@smcdsb.on.ca
  25. @url http://www.jurjans.lv/flash/RegExp.html
  26. */
  27. class Shared.RegExp
  28. {
  29. public var const:String = null;
  30. public var source:String = null;
  31. public var global:Boolean = false;
  32. public var ignoreCase:Boolean = false;
  33. public var multiline:Boolean = false;
  34. public var lastIndex:Number = null;
  35. public static var _xrStatic:Number = null;
  36. public var _xr:Number = null;
  37. public static var _xp:Number = null;
  38. public static var _xxa:Array = null;
  39. public static var _xxlp:Number = null;
  40. public var _xq:Number = null;
  41. public var _xqc:Number = null;
  42. public static var d:Number = null;
  43. public static var _xiStatic:Number = null;
  44. public var _xi:Number = 0;
  45. public static var _xxlm:String = null;
  46. public static var _xxlc:String = null;
  47. public static var _xxrc:String = null;
  48. public static var lastMatch:String = null;
  49. public static var leftContext:String = null;
  50. public static var rightContext:String = null;
  51. public static var _xa:Array = new Array();
  52. public static var lastParen:String = null;
  53. public static var _xaStatic:Array = new Array();
  54. public static var $1:String = null;
  55. public static var $2:String = null;
  56. public static var $3:String = null;
  57. public static var $4:String = null;
  58. public static var $5:String = null;
  59. public static var $6:String = null;
  60. public static var $7:String = null;
  61. public static var $8:String = null;
  62. public static var $9:String = null;
  63. //this device sets up the String prototype functions immediately
  64. private static var _setString:Boolean = RegExp.setStringMethods();
  65. /**
  66. * Instantiates a Regular Expression
  67. * @usage import edu.clips.util.RegExp;<BR>var thing = new RegExp(string, flags, mystery); <BR>
  68. * @param string String defining the pattern
  69. * @param flags some subset of "gim" where g indicates a global search, i a case-insensitive one and m a multi-line one
  70. * @param mystery - I think this is used only internally by the class
  71. * @example import edu.clips.util.RegExp;<BR>var re = new RegExp("\\s+CLIPS","g");
  72. */
  73. function RegExp()
  74. {
  75. if (arguments[0] == null)
  76. {
  77. }
  78. else
  79. {
  80. const = "RegExp";
  81. compile.apply(this,arguments);
  82. }
  83. }
  84. /**Used to determine which version of the class is actually stored and used
  85. *@returns <code>(String)</code> Details of the current version. */
  86. public function getVersionInfo():String
  87. {
  88. return "RegExp Version January 26, 2010";
  89. }
  90. public function invStr(sVal:String):String
  91. {
  92. var s = sVal;
  93. var l = length(s);
  94. var j;
  95. var c;
  96. var r = "";
  97. for (var i = 1; i < 255; i++)
  98. {
  99. c = chr(i);
  100. j = 0;
  101. while (j <= l && substring(s, 1 + j++, 1) != c)
  102. {
  103. }
  104. if (j > l)
  105. {
  106. r += c;
  107. }
  108. }
  109. return s;
  110. }
  111. public function compile()
  112. {
  113. this.source = arguments[0];
  114. if (arguments.length > 1)
  115. {
  116. var flags = (arguments[1] + '').toLowerCase();
  117. for (var i = 0; i < length(flags); i++)
  118. {
  119. if (substring(flags, i + 1, 1) == "g")
  120. {
  121. this.global = true;
  122. }
  123. if (substring(flags, i + 1, 1) == "i")
  124. {
  125. this.ignoreCase = true;
  126. }
  127. if (substring(flags, i + 1, 1) == "m")
  128. {
  129. this.multiline = true;
  130. }
  131. }
  132. }
  133. if (arguments.length < 3)
  134. {
  135. var root = true;
  136. RegExp._xrStatic = 1;
  137. //Paren counter
  138. var i = 0;
  139. }
  140. else
  141. {
  142. var root = false;
  143. this._xr = RegExp._xrStatic++;
  144. var i = arguments[2];
  145. }
  146. this.lastIndex = 0;
  147. /*
  148. Compile the regular expression
  149. The array of character definition objects will be created:
  150. q[n].t --> type of match required: 0 = exact
  151. 1 = in char set
  152. 2 = not in char set
  153. 3 = paren
  154. 4 = ref to paren
  155. 7 = new "OR" section
  156. 9 = beginning of line
  157. 10 = end of line
  158. q[n].s --> character or character set
  159. q[n].a --> character has to repeat at least a times
  160. q[n].b --> character has to repeat at most b times
  161. */
  162. var re = this.source;
  163. var ex;
  164. var l = length(re);
  165. var q = [];
  166. var qc = 0;
  167. var s;
  168. var range = false;
  169. var ca;
  170. var cb;
  171. var atEnd = false;
  172. var char;
  173. for (i = i; i < l; ++i)
  174. {
  175. var thischar = substring(re, i + 1, 1);
  176. if (thischar == "\\")
  177. {
  178. i++;
  179. char = false;
  180. thischar = substring(re, i + 1, 1);
  181. }
  182. else
  183. {
  184. char = true;
  185. }
  186. var nextchar = substring(re, i + 2, 1);
  187. q[qc] = new Object();
  188. q[qc].t = 0;
  189. q[qc].a = 0;
  190. q[qc].b = 999;
  191. q[qc].c = -10;
  192. if (char)
  193. {
  194. // Handle special characters
  195. if (thischar == "(")
  196. {
  197. //Opening paren
  198. ex = new RegExp(re, (this.ignoreCase ? "gi" : "g"), i + 1);
  199. i = RegExp._xiStatic;
  200. q[qc].t = 3;
  201. thischar = ex;
  202. nextchar = substring(re, i + 2, 1);
  203. }
  204. else if (!root && thischar == ")")
  205. {
  206. //Closing paren
  207. break;
  208. }
  209. else if (thischar == "^")
  210. {
  211. //Must be located at the beginning of string/line
  212. if (qc == 0 || q[qc - 1].t == 7)
  213. {
  214. q[qc].t = 9;
  215. q[qc].a = 1;
  216. q[qc].b = 1;
  217. qc++;
  218. }
  219. continue;
  220. }
  221. else if (thischar == "$")
  222. {
  223. //Must be located at the end of string/line
  224. if (root)
  225. {
  226. atEnd = true;
  227. }
  228. continue;
  229. }
  230. else if (thischar == "[")
  231. {
  232. //This is a character set
  233. i++;
  234. if (nextchar == "^")
  235. {
  236. q[qc].t = 2;
  237. i++;
  238. }
  239. else
  240. {
  241. q[qc].t = 1;
  242. }
  243. thischar = "";
  244. range = false;
  245. while (i < l && (s = substring(re, 1 + i++, 1)) != "]")
  246. {
  247. if (range)
  248. {
  249. //Previous char was "-", so create a range
  250. if (s == "\\")
  251. {
  252. }
  253. cb = s == "\\" ? (s == "b" ? chr(8) : substring(re, 1 + i++, 1)) : s;
  254. ca = ord(substring(thischar, length(thischar), 1)) + 1;
  255. while (cb >= (s = chr(ca++)))
  256. {
  257. thischar += s;
  258. }
  259. range = false;
  260. }
  261. else
  262. {
  263. if (s == "-" && length(thischar) > 0)
  264. {
  265. //Character range is being defined
  266. range = true;
  267. }
  268. else
  269. {
  270. if (s == "\\")
  271. {
  272. //Predefined char set may follow
  273. s = substring(re, 1 + i++, 1);
  274. if (s == "d")
  275. {
  276. thischar += "0123456789";
  277. }
  278. else if (s == "D")
  279. {
  280. thischar += invStr("0123456789");
  281. }
  282. else if (s == "s")
  283. {
  284. thischar += " \f\n\r\t\v";
  285. }
  286. else if (s == "S")
  287. {
  288. thischar += invStr(" \f\n\r\t\v");
  289. }
  290. else if (s == "w")
  291. {
  292. thischar += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
  293. }
  294. else if (s == "W")
  295. {
  296. thischar += invStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_");
  297. }
  298. else if (s == "b")
  299. {
  300. thischar += chr(8);
  301. }
  302. else if (s == "\\")
  303. {
  304. thischar += s;
  305. }
  306. }
  307. else
  308. {
  309. thischar += s;
  310. }
  311. }
  312. }
  313. }
  314. if (range)
  315. {
  316. thischar += "-";
  317. }
  318. i--;
  319. var nextchar = substring(re, i + 2, 1);
  320. }
  321. else if (thischar == "|")
  322. {
  323. //OR section
  324. if (atEnd)
  325. {
  326. q[qc].t = 10;
  327. q[qc].a = 1;
  328. q[qc].b = 1;
  329. qc++;
  330. q[qc] = new Object();
  331. atEnd = false;
  332. }
  333. q[qc].t = 7;
  334. q[qc].a = 1;
  335. q[qc].b = 1;
  336. qc++;
  337. continue;
  338. }
  339. else if (thischar == ".")
  340. {
  341. q[qc].t = 2;
  342. thischar = "\n";
  343. }
  344. else if (thischar == "*" || thischar == "?" || thischar == "+")
  345. {
  346. continue;
  347. }
  348. }
  349. else
  350. {
  351. if (thischar >= "1" && thischar <= "9")
  352. {
  353. q[qc].t = 4;
  354. }
  355. else if (thischar == "b")
  356. {
  357. q[qc].t = 1;
  358. thischar = "--wb--";
  359. }
  360. else if (thischar == "B")
  361. {
  362. q[qc].t = 2;
  363. thischar = "--wb--";
  364. }
  365. else if (thischar == "d")
  366. {
  367. q[qc].t = 1;
  368. thischar = "0123456789";
  369. }
  370. else if (thischar == "D")
  371. {
  372. q[qc].t = 2;
  373. thischar = "0123456789";
  374. }
  375. else if (thischar == "s")
  376. {
  377. q[qc].t = 1;
  378. thischar = " \f\n\r\t\v";
  379. }
  380. else if (thischar == "S")
  381. {
  382. q[qc].t = 2;
  383. thischar = " \f\n\r\t\v";
  384. }
  385. else if (thischar == "w")
  386. {
  387. q[qc].t = 1;
  388. thischar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
  389. }
  390. else if (thischar == "W")
  391. {
  392. q[qc].t = 2;
  393. thischar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
  394. }
  395. }
  396. //Counting metacharacters
  397. if (nextchar == "*")
  398. {
  399. q[qc].s = thischar;
  400. qc++;
  401. i++;
  402. }
  403. else if (nextchar == "?")
  404. {
  405. q[qc].s = thischar;
  406. q[qc].b = 1;
  407. qc++;
  408. i++;
  409. }
  410. else if (nextchar == "+")
  411. {
  412. q[qc].s = thischar;
  413. q[qc].a = 1;
  414. qc++;
  415. i++;
  416. }
  417. else if (nextchar == "{")
  418. {
  419. var comma = false;
  420. var rangeA = 0;
  421. range = "";
  422. i++;
  423. while (i + 1 < l && (s = substring(re, 2 + i++, 1)) != "}")
  424. {
  425. if (!comma && s == ",")
  426. {
  427. comma = true;
  428. rangeA = Number(range);
  429. rangeA = Math.floor(isNaN(rangeA) ? 0 : rangeA);
  430. if (rangeA < 0)
  431. {
  432. rangeA = 0;
  433. }
  434. range = "";
  435. }
  436. else
  437. {
  438. range += s;
  439. }
  440. }
  441. var rangeB = Number(range);
  442. rangeB = Math.floor(isNaN(rangeB) ? 0 : rangeB);
  443. if (rangeB < 1)
  444. {
  445. rangeB = 999;
  446. }
  447. if (rangeB < rangeA)
  448. {
  449. rangeB = rangeA;
  450. }
  451. q[qc].s = thischar;
  452. q[qc].b = rangeB;
  453. q[qc].a = comma ? rangeA : rangeB;
  454. qc++;
  455. }
  456. else
  457. {
  458. q[qc].s = thischar;
  459. q[qc].a = 1;
  460. q[qc].b = 1;
  461. qc++;
  462. }
  463. }
  464. if (root && atEnd)
  465. {
  466. q[qc] = new Object();
  467. q[qc].t = 10;
  468. q[qc].a = 1;
  469. q[qc].b = 1;
  470. qc++;
  471. }
  472. if (!root)
  473. {
  474. RegExp._xiStatic = i;
  475. this.source = substring(re, arguments[2] + 1, i - arguments[2]);
  476. }
  477. if (RegExp.d)
  478. {
  479. for (var i = 0; i < qc; i++)
  480. {
  481. trace("xr" + this._xr + ' ' + q[i].t + " : " + q[i].a + " : " + q[i].b + " : " + q[i].s);
  482. }
  483. }
  484. this._xq = q;
  485. this._xqc = qc;
  486. RegExp._xp = 0;
  487. }
  488. /**Used to test whether a string has a pattern defined by the Regular Expression
  489. *@usage re.test(string)
  490. *@param string <code>(String)</code> The string to be searched
  491. *@returns Boolean indicating whether the pattern was found
  492. *@example nameof = "StandardStart27_mc"<BR>var re = new RegExp("Start","g");<BR>trace("Does the string include 'Start'? "+re.test(nameof)); //outputs true*/
  493. public function test()
  494. {
  495. if (RegExp._xp++ == 0)
  496. {
  497. RegExp._xxa = [];
  498. //Temp array for storing paren matches
  499. RegExp._xxlp = 0;
  500. //Last paren
  501. }
  502. // q[n].c --> count of matches
  503. // q[n].i --> index within the string
  504. var str = arguments[0] + '';
  505. var re;
  506. var q = this._xq;
  507. var qc = this._xqc;
  508. var qb;
  509. var c;
  510. var cl;
  511. var ct;
  512. var s;
  513. var l = length(str);
  514. var ix = this.global ? this.lastIndex : 0;
  515. var ix_ = ix;
  516. var str_ = str;
  517. if (this.ignoreCase)
  518. {
  519. str = str.toLowerCase();
  520. }
  521. var r = new Object();
  522. r.i = -1;
  523. var i = -1;
  524. while (i < qc - 1)
  525. {
  526. i++;
  527. if (RegExp.d)
  528. {
  529. trace("New section started at i=" + i);
  530. }
  531. ix = ix_;
  532. qb = i;
  533. q[qb].c = -10;
  534. var atEnd = false;
  535. while (i > qb || ix < l + 1)
  536. {
  537. if (q[i].t == 7)
  538. {
  539. //New "OR" section coming
  540. break;
  541. }
  542. else if (q[i].t == 9)
  543. {
  544. i++;
  545. if (i == qb + 1)
  546. {
  547. var atStart = true;
  548. qb = i;
  549. }
  550. q[qb].c = -10;
  551. continue;
  552. }
  553. else
  554. {
  555. if (r.i >= 0 && ix >= r.i)
  556. {
  557. //There is already better match, so quit searching
  558. break;
  559. }
  560. if (q[i].c == -10)
  561. {
  562. if (RegExp.d)
  563. {
  564. trace("Lookup #" + i + " at index " + ix + " for \\\\\\\\\\\\\\\\'" + q[i].s + "\\\\\\\\\\\\\\\\' type " + q[i].t);
  565. }
  566. //Count the # of matches
  567. var m = 0;
  568. q[i].i = ix;
  569. if (q[i].t == 0)
  570. {
  571. //Exact match
  572. c = this.ignoreCase ? q[i].s.toLowerCase() : q[i].s;
  573. while (m < q[i].b && ix < l)
  574. {
  575. if (substring(str, 1 + ix, 1) == c)
  576. {
  577. m++;
  578. ix++;
  579. }
  580. else
  581. {
  582. break;
  583. }
  584. }
  585. }
  586. else if (q[i].t == 1)
  587. {
  588. //In char set
  589. if (q[i].s == "--wb--")
  590. {
  591. q[i].a = 1;
  592. if (ix > 0 && ix < l)
  593. {
  594. ct = substring(str, ix, 1);
  595. if (ct == " " || ct == "\\\\\\\\\\\\\\\\n")
  596. {
  597. m = 1;
  598. }
  599. if (m == 0)
  600. {
  601. ct = substring(str, 1 + ix, 1);
  602. if (ct == " " || ct == "\\\\\\\\\\\\\\\\n")
  603. {
  604. m = 1;
  605. }
  606. }
  607. }
  608. else
  609. {
  610. m = 1;
  611. }
  612. }
  613. else
  614. {
  615. c = this.ignoreCase ? q[i].s.toLowerCase() : q[i].s;
  616. cl = length(c);
  617. var cs;
  618. while (m < q[i].b && ix < l)
  619. {
  620. ct = substring(str, 1 + ix, 1);
  621. cs = 0;
  622. while (cs <= cl && substring(c, 1 + cs++, 1) != ct)
  623. {
  624. }
  625. if (cs <= cl)
  626. {
  627. m++;
  628. ix++;
  629. }
  630. else
  631. {
  632. break;
  633. }
  634. }
  635. }
  636. }
  637. else if (q[i].t == 2)
  638. {
  639. //Not in char set
  640. c = this.ignoreCase ? q[i].s.toLowerCase() : q[i].s;
  641. cl = length(c);
  642. if (q[i].s == "--wb--")
  643. {
  644. q[i].a = 1;
  645. if (ix > 0 && ix < l)
  646. {
  647. ct = substring(str, ix, 1);
  648. s = substring(str, 1 + ix, 1);
  649. if (ct != " " && ct != "\\\\\\\\\\\\\\\\n" && s != " " && s != "\\\\\\\\\\\\\\\\n")
  650. {
  651. m = 1;
  652. }
  653. }
  654. else
  655. {
  656. m = 0;
  657. }
  658. }
  659. else
  660. {
  661. while (m < q[i].b && ix < l)
  662. {
  663. ct = substring(str, 1 + ix, 1);
  664. cs = 0;
  665. while (cs <= cl && substring(c, 1 + cs++, 1) != ct)
  666. {
  667. }
  668. if (cs <= cl)
  669. {
  670. break;
  671. }
  672. else
  673. {
  674. m++;
  675. ix++;
  676. }
  677. }
  678. }
  679. }
  680. else if (q[i].t == 10)
  681. {
  682. //End of string/line must be next
  683. s = substring(str, 1 + ix, 1);
  684. m = (this.multiline && (s == "\\\\\\\\\\\\\\\\n" || s == "\\\\\\\\\\\\\\\\r")) || ix == l ? 1 : 0;
  685. }
  686. else if (q[i].t == 3)
  687. {
  688. //Regular expression in parens
  689. re = q[i].s;
  690. q[i].ix = [];
  691. q[i].ix[m] = ix;
  692. //Save index if need to retreat
  693. re.lastIndex = ix;
  694. while (m < q[i].b && re.test(str_))
  695. {
  696. cl = length(RegExp._xxlm);
  697. if (cl > 0)
  698. {
  699. ix += cl;
  700. m++;
  701. q[i].ix[m] = ix;
  702. }
  703. else
  704. {
  705. m = q[i].a;
  706. q[i].ix[m - 1] = ix;
  707. break;
  708. }
  709. }
  710. if (m == 0)
  711. {
  712. RegExp._xxlm = "";
  713. }
  714. if (re._xr > RegExp._xxlp)
  715. {
  716. RegExp._xxlp = re._xr;
  717. }
  718. RegExp._xxa[Number(re._xr)] = RegExp._xxlm;
  719. }
  720. else if (q[i].t == 4)
  721. {
  722. //Back reference to paren
  723. if (RegExp._xp >= (c = Number(q[i].s)))
  724. {
  725. c = RegExp._xxa[c];
  726. c = this.ignoreCase ? c.toLowerCase() : c;
  727. cl = length(c);
  728. q[i].ix = [];
  729. q[i].ix[m] = ix;
  730. if (cl > 0)
  731. {
  732. while (m < q[i].b && ix < l)
  733. {
  734. if (substring(str, 1 + ix, cl) == c)
  735. {
  736. m++;
  737. ix += cl;
  738. q[i].ix[m] = ix;
  739. }
  740. else
  741. {
  742. break;
  743. }
  744. }
  745. }
  746. else
  747. {
  748. m = 0;
  749. q[i].a = 0;
  750. }
  751. }
  752. else
  753. {
  754. //Paren is not ready, treat number as charcode
  755. c = chr(c);
  756. q[i].ix = [];
  757. q[i].ix[m] = ix;
  758. while (m < q[i].b && ix < l)
  759. {
  760. if (substring(str, 1 + ix, 1) == c)
  761. {
  762. m++;
  763. ix++;
  764. q[i].ix[m] = ix;
  765. }
  766. else
  767. {
  768. break;
  769. }
  770. }
  771. }
  772. }
  773. q[i].c = m;
  774. if (RegExp.d)
  775. {
  776. trace(" " + m + " matches found");
  777. }
  778. }
  779. if (q[i].c < q[i].a)
  780. {
  781. if (RegExp.d)
  782. {
  783. trace(" not enough matches");
  784. }
  785. //Not enough matches
  786. if (i > qb)
  787. {
  788. //Retreat back and decrease # of assumed matches
  789. i--;
  790. q[i].c--;
  791. if (q[i].c >= 0)
  792. {
  793. ix = (q[i].t == 3 || q[i].t == 4) ? q[i].ix[q[i].c] : (q[i].i + q[i].c);
  794. }
  795. if (RegExp.d)
  796. {
  797. trace("Retreat to #" + i + " c=" + q[i].c + " index=" + ix);
  798. }
  799. }
  800. else
  801. {
  802. if (RegExp._xp > 1)
  803. {
  804. //If this is a paren, failing to find first match is fatal
  805. break;
  806. }
  807. if (atStart)
  808. {
  809. //Match must be at the start of string/line
  810. if (this.multiline)
  811. {
  812. //Jump to the beginning of the next line
  813. while (ix <= l)
  814. {
  815. s = substring(str, 1 + ix++, 1);
  816. if (s == "\\\\\\\\\\\\\\\\n" || s == "\\\\\\\\\\\\\\\\r")
  817. {
  818. break;
  819. }
  820. }
  821. q[i].c = -10;
  822. }
  823. else
  824. {
  825. //No match
  826. break;
  827. }
  828. }
  829. else
  830. {
  831. //Start a new search from next position
  832. ix++;
  833. q[i].c = -10;
  834. }
  835. }
  836. }
  837. else
  838. {
  839. if (RegExp.d)
  840. {
  841. trace(" enough matches!");
  842. }
  843. //# of matches ok, proceed to next
  844. i++;
  845. if (i == qc || q[i].t == 7)
  846. {
  847. if (RegExp.d)
  848. {
  849. trace("Saving better result: r.i = q[" + qb + "].i = " + q[qb].i);
  850. }
  851. r.i = q[qb].i;
  852. r.li = ix;
  853. break;
  854. }
  855. else
  856. {
  857. q[i].c = -10;
  858. }
  859. }
  860. }
  861. }
  862. while (i < qc && q[i].t != 7)
  863. {
  864. i++;
  865. }
  866. //Jump to the next "OR" section
  867. }
  868. if (r.i < 0)
  869. {
  870. this.lastIndex = 0;
  871. if (RegExp._xp-- == 1)
  872. {
  873. RegExp._xxa = [];
  874. RegExp._xxlp = 0;
  875. }
  876. return false;
  877. }
  878. else
  879. {
  880. ix = r.li;
  881. this._xi = r.i;
  882. RegExp._xxlm = substring(str_, r.i + 1, ix - r.i);
  883. RegExp._xxlc = substring(str_, 1, r.i);
  884. RegExp._xxrc = substring(str_, ix + 1, l - ix);
  885. if (ix == r.i)
  886. {
  887. ix++;
  888. }
  889. this.lastIndex = ix;
  890. if (RegExp._xp-- == 1)
  891. {
  892. RegExp.lastMatch = RegExp._xxlm;
  893. RegExp.leftContext = RegExp._xxlc;
  894. RegExp.rightContext = RegExp._xxrc;
  895. RegExp._xaStatic = RegExp._xxa;
  896. RegExp.lastParen = RegExp._xxa[Number(RegExp._xxlp)];
  897. for (i = 1; i < 10; i++)
  898. {
  899. RegExp["$" + i] = RegExp._xaStatic[Number(i)];
  900. }
  901. }
  902. return true;
  903. }
  904. }
  905. /**A RegExp method that executes a search for a match in a string.
  906. *@usage re.exec(string)
  907. *@param string <code>(String)</code> The string to be pattern-matched
  908. *@returns Object with properties index (the position), input (the string) and 0 (the matched character(s))<br>
  909. *Note: previous operations with the RegExp object may affect the last Index being considered and hence the results. Multiple calls to exec are necessary to get all the matches.
  910. *@example p2 = new RegExp("\\d+","g");<br>
  911. next_string = "I have 23 ways to list 5 objects on 217 pieces of paper";<br>
  912. var results1:Object = p2.exec(next_string);<br>
  913. while (results1 != null)<br>
  914. {<br>
  915. for (var prop in results1){<br>
  916. trace(" * "+prop+" : "+results1[prop]);<br>
  917. }<br>
  918. results1 = p2.exec(next_string);<br>
  919. }<br>*/
  920. public function exec()
  921. {
  922. var str = arguments[0] + '';
  923. if (str == '')
  924. {
  925. return false;
  926. }
  927. var t = this.test(str);
  928. if (t)
  929. {
  930. var ra = new Array();
  931. ra.index = this._xi;
  932. ra.input = str;
  933. ra[0] = RegExp.lastMatch;
  934. var l = RegExp._xaStatic.length;
  935. for (var i = 1; i < l; i++)
  936. {
  937. ra[i] = RegExp._xaStatic[Number(i)];
  938. }
  939. }
  940. else
  941. {
  942. var ra = null;
  943. }
  944. return ra;
  945. }
  946. public static function setStringMethods()
  947. {
  948. trace("setStringMethods being defined");
  949. if (String.prototype.match != undefined)
  950. {
  951. trace("Warning - match is already defined, String.prototype functions will be overridden");
  952. //return;
  953. }
  954. if (String.prototype.replace != undefined)
  955. {
  956. trace("Warning - replace is being replaced");
  957. }
  958. /**Finds the characters that match the pattern defined by the regular expression.<br>
  959. Use the "g" flag to repeat the process over and over. <br>
  960. Added to String.prototype so that it can be used with any string.
  961. Changed on January 26, 2010 to return a string - not sure how that will affect multiple calls with the "g" flag
  962. *@usage string.match(re)
  963. *@param string <code>(String)</code> The string to be pattern-matched
  964. *@returns Array with every matched set of characters
  965. *@example nameof = "StandardStart27_mc"; <br>
  966. p2 = new RegExp("\\d+","g");<br>
  967. trace("The digits are " + nameof.match(p2)[0]); //output 27<br>*/
  968. //public function match(re:RegExp):Array{
  969. String.prototype.match = function()
  970. {
  971. if (typeof (arguments[0]) != "object")
  972. {
  973. return null;
  974. }
  975. if (arguments[0].const != "RegExp")
  976. {
  977. trace("Warning - match not sent a RegExp");
  978. return null;
  979. }
  980. var re = arguments[0];
  981. var s = this.valueOf();
  982. var ip = 0;
  983. var rc = 0;
  984. if (re.global)
  985. {
  986. re.lastIndex = 0;
  987. while (re.test(s))
  988. {
  989. if (rc == 0)
  990. {
  991. var ra = new Array();
  992. }
  993. ra[rc++] = RegExp.lastMatch;
  994. ip = re.lastIndex;
  995. }
  996. re.lastIndex = ip;
  997. }
  998. else
  999. {
  1000. var ra = re.exec(s);
  1001. rc++;
  1002. }
  1003. return (rc == 0) ? null : ra;
  1004. };
  1005. /**Replace the characters that match the pattern defined by the regular expression with another string.<br>
  1006. *or Replace the given substring with another one (Based on a idea of Davide Beltrame (Broly))
  1007. *found on <a href='http://www.sephiroth.it/proto_detail.php?id=16'>http://www.sephiroth.it/proto_detail.php?id=16</a><br>
  1008. Added to String.prototype so that it can be used with any string.
  1009. *@usage string.replace(re, new_string);
  1010. *@usage string.replace(found_string, new_string);
  1011. *@param re <code>(RegExp)</code> The Regular Expression with the pattern to be matched
  1012. *@param found_string <code>(String)</code> The string to be matched
  1013. *@param new_string <code>(String)</code> The string to use in the replacement
  1014. *@returns String with replacement(s) made.
  1015. *@example test_txt = " swf Missippi River "; <br>
  1016. p1 = new RegExp("\\s+","g");<br>
  1017. trace(test_txt.replace(p1,"*")); //output '*swf*Missippi*River*'<br><br>
  1018. *@example test = ".swflib/actions/test.swf is a .swf";<br>
  1019. * trace(test+", "+test.replace('.swf', '')); //.swflib/actions/test.swf is a .swf, lib/actions/test is a<br>
  1020. */
  1021. //public function replace(re:RegExp, new_string:String):String{
  1022. String.prototype.replace = function()
  1023. {
  1024. if (typeof (arguments[0]) != "object")
  1025. {
  1026. trace("Warning - replace not sent an Object");
  1027. //return null;
  1028. }
  1029. if (arguments[0].const != "RegExp")
  1030. {
  1031. //definition when the first argument is a String
  1032. var arg_search, arg_replace, position;
  1033. var endText, preText, newText;
  1034. arg_search = arguments[0];
  1035. arg_replace = arguments[1];
  1036. if (arg_search.length == 1)
  1037. {
  1038. return this.split(arg_search).join(arg_replace);
  1039. }
  1040. position = this.indexOf(arg_search);
  1041. if (position == -1)
  1042. {
  1043. return this;
  1044. }
  1045. endText = this;
  1046. newText = "";
  1047. do
  1048. {
  1049. position = endText.indexOf(arg_search);
  1050. preText = endText.substring(0, position);
  1051. endText = endText.substring(position + arg_search.length);
  1052. newText += preText + arg_replace;
  1053. } while (endText.indexOf(arg_search) != -1);
  1054. newText += endText;
  1055. trace("replace returning a result based on a string object");
  1056. return newText;
  1057. }
  1058. var re = arguments[0];
  1059. var rs = arguments[1] + '';
  1060. var s = this;
  1061. var r = "";
  1062. re.lastIndex = 0;
  1063. if (re.global)
  1064. {
  1065. var ip = 0;
  1066. var ix = 0;
  1067. while (re.test(s))
  1068. {
  1069. //Replace backreferences in rs
  1070. var i = 0;
  1071. var l = length(rs);
  1072. var c = "";
  1073. var pc = "";
  1074. var nrs = "";
  1075. while (i < l)
  1076. {
  1077. c = substring(rs, 1 + i++, 1);
  1078. if (c == "$" && pc != "\\")
  1079. {
  1080. c = substring(rs, 1 + i++, 1);
  1081. if (isNaN(Number(c)) || Number(c) > 9)
  1082. {
  1083. nrs += "$" + c;
  1084. }
  1085. else
  1086. {
  1087. nrs += RegExp._xaStatic[Number(c)];
  1088. }
  1089. }
  1090. else
  1091. {
  1092. nrs += c;
  1093. }
  1094. pc = c;
  1095. }
  1096. r += substring(s, ix + 1, re._xi - ix) + nrs;
  1097. ix = re._xi + length(RegExp.lastMatch);
  1098. ip = re.lastIndex;
  1099. }
  1100. re.lastIndex = ip;
  1101. }
  1102. else
  1103. {
  1104. if (re.test(s))
  1105. {
  1106. r += RegExp.leftContext + rs;
  1107. }
  1108. }
  1109. r += re.lastIndex == 0 ? s : RegExp.rightContext;
  1110. return r;
  1111. };
  1112. /**Trim whitespace from the beginning of a string.<br>
  1113. *Added to the class, informed by <a href='http://www.somacon.com/p355.php'>http://www.somacon.com/p355.php</a><br>
  1114. *Added to String.prototype so that it can be used with any string.
  1115. *@usage string.ltrim();
  1116. *@returns trimmed String
  1117. *@example test_txt = "&nbsp;&nbsp;swf&nbsp;&nbsp;&nbsp;Missippi&nbsp;River&nbsp;&nbsp;&nbsp;&nbsp;"; <br>
  1118. trace(test_txt.ltrim()); //output 'swf&nbsp;&nbsp;&nbsp;Missippi&nbsp;River&nbsp;&nbsp;&nbsp;&nbsp;'<br><br>
  1119. */
  1120. //public function ltrim():String{
  1121. String.prototype.ltrim = function()
  1122. {
  1123. var re = new RegExp("^\\s+");
  1124. return this.replace(re, "");
  1125. };
  1126. /**Trim whitespace from the end of a string.<br>
  1127. *Added to the class, informed by <a href='http://www.somacon.com/p355.php'>http://www.somacon.com/p355.php</a><br>
  1128. *Added to String.prototype so that it can be used with any string.
  1129. *@usage string.rtrim();
  1130. *@returns trimmed String
  1131. *@example test_txt = "&nbsp;&nbsp;swf&nbsp;&nbsp;&nbsp;Missippi&nbsp;River&nbsp;&nbsp;&nbsp;&nbsp;"; <br>
  1132. trace(test_txt.rtrim()); //output '&nbsp;&nbsp;swf&nbsp;&nbsp;&nbsp;Missippi&nbsp;River'<br><br>
  1133. */
  1134. //public function rtrim():String{
  1135. String.prototype.rtrim = function()
  1136. {
  1137. var re = new RegExp("\\s+$");
  1138. return this.replace(re, "");
  1139. };
  1140. /**Trim whitespace from the beginning and end of a string.<br>
  1141. *Added to the class by the CLIPS team<br>
  1142. *Added to String.prototype so that it can be used with any string.
  1143. *@usage string.trim();
  1144. *@returns trimmed String
  1145. *@example test_txt = "&nbsp;&nbsp;swf&nbsp;&nbsp;&nbsp;Missippi&nbsp;River&nbsp;&nbsp;&nbsp;&nbsp;"; <br>
  1146. trace(test_txt.trim()); //output 'swf&nbsp;&nbsp;&nbsp;Missippi&nbsp;River'<br><br>
  1147. */
  1148. //public function trim():String{
  1149. String.prototype.trim = function()
  1150. {
  1151. //This device is used since the RegExp for whitespace at both ends didn't seem to work.
  1152. return this.rtrim().ltrim();
  1153. };
  1154. /**Tests for a match in a string.<br>
  1155. *Added to String.prototype so that it can be used with any string.
  1156. *@usage string.search(re);
  1157. *@returns the index of the match, or -1 if the search fails.
  1158. *@example test_txt = "Therrrre Grrrrrrrrrreat"; <br>
  1159. re = new RegExp("r+e","g");
  1160. trace(test_txt.search(re)); //output 3<br><br>
  1161. *@see test
  1162. */
  1163. //public function search(re:RegExp):String{
  1164. String.prototype.search = function()
  1165. {
  1166. if (typeof (arguments[0]) != "object")
  1167. {
  1168. return null;
  1169. }
  1170. if (arguments[0].const != "RegExp")
  1171. {
  1172. trace("Warning - search not sent a RegExp");
  1173. return null;
  1174. }
  1175. var re = arguments[0];
  1176. var s = this;
  1177. re.lastIndex = 0;
  1178. var t = re.test(s);
  1179. return t ? re._xi : -1;
  1180. };
  1181. String.prototype.old_split = String.prototype.split;
  1182. /**Adds the ability to split a string based on a RegExp.<br>
  1183. *Added to String.prototype so that it can be used with any string.
  1184. *@usage string.split(re);
  1185. *@usage string.split(string_delimiter, limit);
  1186. *@param re the RegExp
  1187. *@param string_delimiter the simple string to delimit by
  1188. *@param limit the number of items to place in the array
  1189. *@returns an Array of substrings
  1190. *@example test_txt = "Therrrre Grrrrrrrrrreat"; <br>
  1191. re = new RegExp("r+e","g");<br>
  1192. trace(test_txt.split(re)); //output [The, G,at]<br>
  1193. trace(test_txt.split("r"); //output [The,,,,e G,,,,,,,,,,eat]<br><br>
  1194. */
  1195. //public function split(re:RegExp):String{
  1196. String.prototype.split = function()
  1197. {
  1198. if (typeof (arguments[0]) == "object" && arguments[0].const == "RegExp")
  1199. {
  1200. var re = arguments[0];
  1201. var lm = arguments[1] == null ? 9999 : Number(arguments[1]);
  1202. if (isNaN(lm))
  1203. {
  1204. lm = 9999;
  1205. }
  1206. var s = this;
  1207. var ra = new Array();
  1208. var rc = 0;
  1209. var gs = re.global;
  1210. re.global = true;
  1211. re.lastIndex = 0;
  1212. var ip = 0;
  1213. var ipp = 0;
  1214. var ix = 0;
  1215. while (rc < lm && re.test(s))
  1216. {
  1217. //trace(re._xi + " " + ix + " " + RegExp.lastMatch);
  1218. if (re._xi != ix)
  1219. {
  1220. ra[rc++] = substring(s, ix + 1, re._xi - ix);
  1221. }
  1222. ix = re._xi + length(RegExp.lastMatch);
  1223. ipp = ip;
  1224. ip = re.lastIndex;
  1225. }
  1226. if (rc == lm)
  1227. {
  1228. re.lastIndex = ipp;
  1229. }
  1230. else
  1231. {
  1232. re.lastIndex = ip;
  1233. }
  1234. if (rc == 0)
  1235. {
  1236. ra[rc] = s;
  1237. }
  1238. else
  1239. {
  1240. if (rc < lm && length(RegExp.rightContext) > 0)
  1241. {
  1242. ra[rc++] = RegExp.rightContext;
  1243. }
  1244. }
  1245. re.global = gs;
  1246. return ra;
  1247. }
  1248. else
  1249. {
  1250. return this.old_split(arguments);
  1251. }
  1252. };
  1253. return true;
  1254. }
  1255. }