Str Lib

String helper functions

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/27278/175156/Str%20Lib.js

  1. (function (global, Str) {
  2. "use strict";
  3.  
  4. // region [ Private Functions ]
  5. /**
  6. * Test if the specified object is an array.
  7. * @param obj {Array|object}
  8. * @returns {boolean}
  9. * @private
  10. */
  11. function _isArray(obj) {
  12. return Object.prototype.toString.call(obj) === '[object Array]';
  13. }
  14.  
  15. /**
  16. * Convert json string into js object.
  17. * @param s
  18. * @private
  19. */
  20. function _parseJson(s) {
  21. var _parser;
  22. if (typeof global.JSON !== 'undefined') {
  23. _parser = global.JSON.parse;
  24. }
  25. else if (typeof window.jQuery !== 'undefined') {
  26. _parser = window.jQuery.parseJSON;
  27. }
  28.  
  29. if (typeof _parser === 'undefined') {
  30. throw 'Undefined JSON method';
  31. }
  32. return _parser(s);
  33. }
  34.  
  35. // endregion
  36.  
  37. /**
  38. * Check for undefined, null, zero length, blanks or s is false.
  39. * @param s {string|object} - string, array or object to test.
  40. * @returns {boolean}
  41. * Unit Test: http://jsfiddle.net/wao20/TGP3N/
  42. */
  43. Str.empty = function (s) {
  44. // s == undefined <= double equals is deliberate, check for null and undefined
  45. return !!(s == undefined
  46. || s.length === 0
  47. || Str.trim(s).length === 0
  48. || !s);
  49.  
  50. };
  51.  
  52. /**
  53. * Compare two strings
  54. * @param s1 {?string}
  55. * @param s2 {?string}
  56. * @param caseSensitive {boolean=}
  57. * @returns {boolean}
  58. */
  59. Str.equals = function (s1, s2, caseSensitive) {
  60. if (s1 == undefined || s2 == undefined) {
  61. return false;
  62. }
  63.  
  64. if (caseSensitive) {
  65. return s1 == s2;
  66. }
  67. return s1.toLowerCase() == s2.toLowerCase();
  68. };
  69.  
  70. /**
  71. * empty(), '0', '0.0', 'false' => false. Otherwise return !!s.
  72. *
  73. * @param s {?string}
  74. * @returns {boolean}
  75. */
  76. Str.boolVal = function (s) {
  77. if (Str.empty(s)) {
  78. return false;
  79. }
  80. s = Str.trim(s).toLowerCase();
  81. if (s == '0' || s == '0.0' || s == 'false') {
  82. return false;
  83. }
  84. return !!s;
  85. };
  86.  
  87. /**
  88. * Escape the string to be use as a literal in regex expression.
  89. *
  90. * @param s {string|Array}
  91. * @returns {string|Array}
  92. */
  93. Str.regexEscape = function (s) {
  94. if (!s) {
  95. return '';
  96. }
  97.  
  98. if (typeof s === 'string') {
  99. return s.replace(/([.?*+\^$\[\]\\(){}|\-])/g, '\\$1');
  100. }
  101. else if (_isArray(s)) {
  102. var result = [], i;
  103. for (i = 0; i < s.length; i++) {
  104. result.push(Str.regexEscape(s[i]));
  105. }
  106. return result;
  107. }
  108. return s;
  109. };
  110.  
  111. /**
  112. * Tests whether the beginning of a string matches pattern.
  113. *
  114. * @param s {string}
  115. * @param pattern {string} - to find
  116. * @param caseSensitive {boolean=}
  117. * @return {boolean}
  118. */
  119. Str.startsWith = function (s, pattern, caseSensitive) {
  120. if (caseSensitive) {
  121. return s.indexOf(pattern) === 0;
  122. }
  123. return s.toLowerCase().indexOf(pattern.toLowerCase()) === 0;
  124. };
  125.  
  126. /**
  127. * Test if string ends with specified pattern
  128. * @param s {string}
  129. * @param pattern {string}
  130. * @param caseSensitive {boolean=}
  131. * @returns {boolean}
  132. */
  133. Str.endsWith = function (s, pattern, caseSensitive) {
  134. var d = s.length - pattern.length;
  135. if (caseSensitive) {
  136. return d >= 0 && s.lastIndexOf(pattern) === d;
  137. }
  138. return d >= 0 && s.toLowerCase().lastIndexOf(pattern.toLowerCase()) === d;
  139. };
  140.  
  141. /**
  142. * Check if the string contains a substring.
  143. * @param s {string}
  144. * @param needle {string}
  145. * @param caseSensitive {boolean=}
  146. * @return {boolean}
  147. */
  148. Str.contains = function (s, needle, caseSensitive) {
  149. if (Str.empty(s) || Str.empty(needle)) {
  150. return false;
  151. }
  152. if (caseSensitive) {
  153. return s.indexOf(needle) > -1;
  154. }
  155. return s.toLowerCase().indexOf(needle.toLowerCase()) > -1;
  156. };
  157.  
  158. /**
  159. * Must contains all the element in the array.
  160. * @param s {string}
  161. * @param needles {Array|string}
  162. * @param caseSensitive {boolean=}
  163. * @return {boolean}
  164. */
  165. Str.containsAll = function (s, needles, caseSensitive) {
  166. var i = 0;
  167. if (_isArray(needles)) {
  168. for (i = 0; i < needles.length; i++) {
  169. if (!Str.contains(s, needles[i], caseSensitive)) {
  170. return false;
  171. }
  172. }
  173. return true;
  174. }
  175. return Str.contains(s, needles, caseSensitive);
  176. };
  177.  
  178. /**
  179. * Must contains ANY the element in the array.
  180. * @param s {string}
  181. * @param needles {Array|string}
  182. * @param caseSensitive {boolean=}
  183. * @return {boolean}
  184. */
  185. Str.containsAny = function (s, needles, caseSensitive) {
  186. var i;
  187. if (_isArray(needles)) {
  188. for (i = 0; i < needles.length; i++) {
  189. if (Str.contains(s, needles[i], caseSensitive)) {
  190. return true;
  191. }
  192. }
  193. return false;
  194. }
  195. return Str.contains(s, needles, caseSensitive);
  196. };
  197.  
  198. /**
  199. * Determine if the specified variable is a string
  200. * @param o
  201. * @returns {boolean}
  202. */
  203. Str.isString = function (o) {
  204. return typeof o === 'string';
  205. };
  206.  
  207. /**
  208. * Trims white space from the beginning and end of a string.
  209. * @param s {string}
  210. * @param c {string=}
  211. * @return {string}
  212. */
  213. Str.trim = function (s, c) {
  214. if (!Str.isString(s)) {
  215. return s;
  216. }
  217.  
  218. if (c == undefined || c == ' ') {
  219. if (String.prototype.trim) {
  220. return String.prototype.trim.call(s);
  221. }
  222. return s.replace(/^\s+/, '').replace(/\s+$/, '');
  223. }
  224. return Str.trimStart(Str.trimEnd(s, c), c);
  225. };
  226.  
  227. /**
  228. * Remove chars/Str from the start of the string
  229. * @param s
  230. * @param c {string|Array=} - supports Str.trimStart(s, ['0x0', '0', 'x']);
  231. */
  232. Str.trimStart = function (s, c) {
  233. if (c == undefined || c == '') {
  234. return s.replace(/^\s+/, '');
  235. }
  236.  
  237. var trims = c, regex, result;
  238. if (!_isArray(c)) {
  239. trims = [c];
  240. }
  241. trims = Str.regexEscape(trims).join('|');
  242. regex = '^(' + trims + '|\s)+';
  243. regex = new RegExp(regex, 'g');
  244. result = s.replace(regex, '');
  245. return result;
  246. };
  247.  
  248. /**
  249. * Remove chars/Str(s) from the end of the string
  250. * @param s {string}
  251. * @param c {string|Array=} - supports Str.trimEnd(s, ['0x0', '0', 'x']);
  252. */
  253. Str.trimEnd = function (s, c) {
  254. if (c == undefined) {
  255. return s.replace(/\s+$/, '');
  256. }
  257. var trims = c, regex, result;
  258. if (!_isArray(c)) {
  259. trims = [c];
  260. }
  261. trims = Str.regexEscape(trims).join('|');
  262. regex = '(' + trims + '|\s)+$';
  263. regex = new RegExp(regex, 'g');
  264. result = s.replace(regex, '');
  265. return result;
  266. };
  267.  
  268. /**
  269. * Extended substring, support negative index (ordinal js substr(startIndex, endIndex))
  270. *
  271. * @param s {string}
  272. * @param index {number} - if negative take string from the right similar to php substr()
  273. * @param len {number=} - number of char to take starting from the index to the right (even when index is negative)
  274. * @return {string}
  275. */
  276. Str.subStr = function (s, index, len) {
  277. if (s == undefined) {
  278. return '';
  279. }
  280.  
  281. len = len || 0;
  282.  
  283. if (Math.abs(index) > s.length) {
  284. return s;
  285. }
  286.  
  287. // regular substring
  288. if (index > -1) {
  289. if (len > 0 && (index + len) < s.length) {
  290. return s.substring(index, index + len);
  291. }
  292. return s.substring(index);
  293. }
  294.  
  295. // Negative index, take string from the right
  296. // Index is negative => subStr ('hello', -3) => 'llo'
  297. var start = s.length + index;
  298. if (len > 0 && (start + len) < s.length) {
  299. return s.substring(start, start + len);
  300. }
  301. return s.substring(start);
  302. };
  303.  
  304. /**
  305. * Count number of occurrences of an substring.
  306. * @param s {string} - the big string
  307. * @param sub {string} - the little string you want to find.
  308. * @param caseSensitive {boolean=}
  309. * @returns {number}
  310. */
  311. Str.subCount = function (s, sub, caseSensitive) {
  312. sub = Str.regexEscape(sub);
  313.  
  314. if (caseSensitive) {
  315. return s.split(sub).length - 1;
  316. }
  317. return s.toLowerCase().split(sub.toLowerCase()).length - 1;
  318. };
  319.  
  320. /**
  321. * Concatenate count number of copies of s together and return result.
  322. * @param s {string}
  323. * @param count {number} - Number of times to repeat s
  324. * @return {string}
  325. */
  326. Str.repeat = function (s, count) {
  327. var result = '', i;
  328. for (i = 0; i < count; i++) {
  329. result += s;
  330. }
  331. return result;
  332. };
  333.  
  334. /**
  335. * Pad left
  336. *
  337. * @param s {!string}
  338. * @param padStr {!string} - the padding
  339. * @param totalLength {!number} - the final length after padding
  340. * @return {string}
  341. */
  342. Str.padLeft = function (s, padStr, totalLength) {
  343. return s.length >= totalLength ? s : Str.repeat(padStr, (totalLength - s.length) / padStr.length) + s;
  344. };
  345.  
  346. /**
  347. * Pad right
  348. *
  349. * @param s {string}
  350. * @param padStr {string} - the padding
  351. * @param totalLength {number} - the final length after padding
  352. * @return {string}
  353. */
  354. Str.padRight = function (s, padStr, totalLength) {
  355. return s.length >= totalLength ? s : s + Str.repeat(padStr, (totalLength - s.length) / padStr.length);
  356. };
  357.  
  358. /**
  359. * Pad string based on the boolean value.
  360. *
  361. * @param s {string}
  362. * @param padStr {string} - the padding
  363. * @param totalLength {number} - the final length after padding
  364. * @param padRight {boolean} - pad right if true, pad left otherwise
  365. * @return {string}
  366. */
  367. Str.pad = function (s, padStr, totalLength, padRight) {
  368. if (padRight) {
  369. return Str.padRight(s, padStr, totalLength);
  370. }
  371. return Str.padLeft(s, padStr, totalLength);
  372. };
  373.  
  374. /**
  375. * Strips any HTML tags from the specified string.
  376. * @param s {string}
  377. * @return {string}
  378. */
  379. Str.stripTags = function (s) {
  380. return s.replace(/<\/?[^>]+>/gi, '');
  381. };
  382.  
  383. /**
  384. * escapeHTML from Prototype-1.6.0.2 -- If it's good enough for Webkit and IE, it's good enough for Gecko!
  385. * Converts HTML special characters to their entity equivalents.
  386. *
  387. * @param s {string}
  388. * @return {string}
  389. */
  390. Str.escapeHTML = function (s) {
  391. s = s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
  392. return s;
  393. };
  394.  
  395. /**
  396. * unescapeHTML from Prototype-1.6.0.2 -- If it's good enough for Webkit and IE, it's good enough for Gecko!
  397. * Strips tags and converts the entity forms of special HTML characters to their normal form.
  398. *
  399. * @param s {string}
  400. * @return {string}
  401. */
  402. Str.unescapeHTML = function (s) {
  403. return Str.stripTags(s).replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
  404. };
  405.  
  406. /**
  407. * Remove all Viet's accents and replace it with the latin based alphabet
  408. * @param s {string}
  409. * @return {string}
  410. */
  411. Str.stripViet = function (s) {
  412. /*
  413. data = data.replace(/[àáâãăạảấầẩẫậắằẳẵặ]/g, 'a');
  414. data = data.replace(/[òóôõơọỏốồổỗộớờởỡợ]/g, 'o');
  415. data = data.replace(/[èéêẹẻẽếềểễệ]/g, 'e');
  416. data = data.replace(/[ùúũưụủứừửữự]/g, 'u');
  417. data = data.replace(/[ìíĩỉị]/g, 'i');
  418. data = data.replace(/[ýỳỵỷỹ]/g, 'y');
  419. data = data.replace(/[đðĐ]/g, 'd');
  420. */
  421.  
  422. if (Str.empty(s)) {
  423. return s;
  424. }
  425.  
  426. s = s.replace(/[\u00E0\u00E1\u00E2\u00E3\u0103\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7]/g, 'a');
  427. s = s.replace(/[\u00F2\u00F3\u00F4\u00F5\u01A1\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3]/g, 'o');
  428. s = s.replace(/[\u00E8\u00E9\u00EA\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7]/g, 'e');
  429. s = s.replace(/[\u00F9\u00FA\u0169\u01B0\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1]/g, 'u');
  430. s = s.replace(/[\u00EC\u00ED\u0129\u1EC9\u1ECB]/g, 'i');
  431. s = s.replace(/[\u00FD\u1EF3\u1EF5\u1EF7\u1EF9]/g, 'y');
  432. s = s.replace(/[\u0111\u00F0\u0110]/g, 'd');
  433.  
  434. return s;
  435. };
  436.  
  437. /**
  438. * Use this to constructs multi lines string
  439. *
  440. * eg. Str.multiLines(true,
  441. * 'hello',
  442. * 'world'
  443. * );
  444. * returns: "hello\nworld"
  445. *
  446. * @param glue {string} - the separator between each line (eg. '\n', ', ' or ' ')
  447. * @param args {...string} - each line
  448. */
  449. Str.multiLines = function (glue, args) {
  450. args = Array.prototype.splice.call(arguments, 1);
  451. return args.join(glue);
  452. };
  453.  
  454. /**
  455. * Try to parse the json, if valid return the object else return defaultValue
  456. *
  457. * @param s {string} - json string
  458. * @param defaultValue {boolean|object=} - if not specified defaultValue=false
  459. * @returns {boolean|object}
  460. */
  461. Str.parseJson = function (s, defaultValue) {
  462. defaultValue = defaultValue === undefined ? false : defaultValue;
  463. if (Str.empty(s)) {
  464. return defaultValue;
  465. }
  466.  
  467. try {
  468. if (typeof s === 'string') {
  469. return _parseJson(s);
  470. }
  471.  
  472. // it already an object
  473. return s;
  474. }
  475. catch (err) {
  476. return defaultValue;
  477. }
  478. };
  479.  
  480. /**
  481. * Escape the attribute, make sure it doesn't break the attribute select or to be use a an attribute.
  482. * @param s {string} - the string
  483. */
  484. Str.escapeAttribute = function (s) {
  485. return s.replace(/"/g, '\\"');
  486. };
  487.  
  488. /**
  489. * Reverse the string.
  490. *
  491. * @param s
  492. * @returns {*}
  493. */
  494. Str.reverse = function (s) {
  495. if (s) {
  496. return s.split('').reverse().join('');
  497. }
  498. return s;
  499. };
  500.  
  501. /**
  502. * Get all the matched based on the specified group.
  503. *
  504. * @param s {string}
  505. * @param regex {RegExp}
  506. * @param index {Number} - the index of the match.
  507. * @returns {Array}
  508. */
  509. Str.matchAll = function (s, regex, index) {
  510. var m, result = [];
  511. index = index || 0;
  512.  
  513. if (!s) {
  514. return [];
  515. }
  516.  
  517. while (m = regex.exec(s)) {
  518. result.push(m[index]);
  519. }
  520. return result;
  521. };
  522.  
  523. /**
  524. * Split the string into multiple smaller chunks.
  525. *
  526. * @param s
  527. * @param chunkSize
  528. * @returns {Array}
  529. */
  530. Str.chop = function (s, chunkSize) {
  531. var regex;
  532. if (!s) {
  533. return [];
  534. }
  535. regex = new RegExp('.{1,' + chunkSize + '}', 'g');
  536. return s.match(regex);
  537. };
  538.  
  539. function _getWords(s) {
  540. s = s.replace(/(\w)([A-Z][a-z])/, '$1-$2');
  541. s = s.replace(' ', '-');
  542. s = s.replace('_', '-');
  543. s = s.replace(/-+/g, '-');
  544.  
  545. return s.split('-')
  546. }
  547.  
  548. /**
  549. * Convert any string to camel case.
  550. *
  551. * @param s
  552. */
  553. Str.toCamelCase = function (s) {
  554. var words = _getWords(s), result = '', i, word;
  555. for (i = 0; i < words.length; i++) {
  556. word = words[i];
  557. if (i == 0) {
  558. result += word.toLowerCase();
  559. }
  560. else {
  561. result += word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
  562. }
  563. }
  564. return result;
  565. };
  566.  
  567. /**
  568. * Convert any string to title case.
  569. *
  570. * @param s
  571. */
  572. Str.toTitleCase = function (s) {
  573. var words = _getWords(s), result = '', i, word;
  574. for (i = 0; i < words.length; i++) {
  575. word = words[i];
  576. result += word.charAt(0).toUpperCase() + word.substr(1).toLowerCase() + ' ';
  577. }
  578. return Str.trimEnd(result);
  579. };
  580.  
  581. /**
  582. * Convert any string to snake case.
  583. *
  584. * @param s
  585. */
  586. Str.toSnakeCase = function (s) {
  587. var words = _getWords(s), result = '', i, word;
  588. for (i = 0; i < words.length; i++) {
  589. word = words[i];
  590. result += word.toLowerCase() + '_';
  591. }
  592. return Str.trimEnd(result, '_');
  593. };
  594.  
  595. /**
  596. * Convert any string to-kebab-case.
  597. *
  598. * @param s
  599. */
  600. Str.toKebabCase = function (s) {
  601. var words = _getWords(s), result = '', i, word;
  602. for (i = 0; i < words.length; i++) {
  603. word = words[i];
  604. result += word.toLowerCase() + '-';
  605. }
  606. return Str.trimEnd(result, '-');
  607. };
  608.  
  609. }(window, window._Str = {}));

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址