在分号之间用字母数字字符

时间:2018-01-16 05:02:24

标签: javascript regex

我们说我们有这些字符串:

1. "a;b;c;d;e"
2. "1;2;3;4;5"
3. "!@#$%^&*()_+;!@#$%^&*()_+;"

有没有办法让我们在调用.split(';')时只会在;介于字母数字字符之间时拆分?

预期结果:

1. a, b, c, d, e
2. 1, 2, 3, 4, 5
3. !@#$%^&*()_+;!@#$%^&*()_+; // kept as is

这就是我到目前为止所做的事情,但它并没有在我预期的地方完全分开#34;它起作用。

.split(/[A-Za-z0-9];[A-Za-z0-9]/g);

目前的结果:

1. (3) ["", ";", ";e"] // no
2. (3) ["", ";", ";5"] // no
3. ["!@#$%^&*()_+;!@#$%^&*()_+;"] // yes

只是为了更新。这不是一个字符串数组。上面的字符串只是样本。还要澄清我期望发生的事情。

分号必须以数字或字母开头并以其开头。

Yes - both characters beside the ; must be a letter or a number
a;b > a, b
1;2 > 1, 2
c;3 > c, 3
4;d > 4, d
5;6;a; > 5, 6, a 

No - when either of the characters beside the ; is not a letter or a number
!;@
12$;525
aa;!$242
bbbbbb;

另一次更新 answer anubhava就像魅力一样,但我在这个特定的字符串中遇到了一些问题。

TestTEST!@#$%^&*()_+{}|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499;TestTEST!@#$%^&*()_+{}|\":?><,./‌​;'[]\\=-this is a long text.test 123455899949949494949499499

他的答案是/([A-Za-z0-9]+);(?=[A-Za-z0-9])/。但是将上述正则表达式用于上面的字符串将导致

(3) 
"TestTEST!@#$%^&*()_+{}|":?><,./;'[]\=-this is a long text.test ",
"123455899949949494949499499",
"TestTEST!@#$%^&*()_+{}|":?><,./;'[]\=-this is a long text.test 123455899949949494949499499"

当预期为

"TestTEST!@#$%^&*()_+{}|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499499"
"TestTEST!@#$%^&*()_+{}|\":?><,./‌​;'[]\\=-this is a long text.test 123455899949949494949499499"

3 个答案:

答案 0 :(得分:3)

您可以使用正面和负面lookaheads来确保分号前面和后面跟着您想要的字符。所以,这将有效:

&#13;
&#13;
let t1 = "a;b;c;d;e";
let t2 = "1;2;3;4;5";
let t3 = "!@#$%^&*()_+;!@#$%^&*()_+;";

console.log(t1.split(/(?![A-Za-z0-9]);(?=[A-Za-z0-9])/g)); // a, b, c, d, e
console.log(t2.split(/(?![A-Za-z0-9]);(?=[A-Za-z0-9])/g)); // 1, 2, 3, 4, 5
console.log(t3.split(/(?![A-Za-z0-9]);(?=[A-Za-z0-9])/g)); // !@#$%^&*()_+;!@#$%^&*()_+;
&#13;
&#13;
&#13;

目前,您的正则表达式匹配一个字母数字字符,后跟一个分号和另一个字母数字字符。

答案 1 :(得分:1)

它出现在现代浏览器中Javascript已开始支持lookbehind。

如果是这种情况那么你的解决方案是一个简单的前瞻和后瞻性正则表达式:

/(?<=[a-z0-9]);(?=[a-z0-9])/i
  • (?<=[a-z0-9]):断言我们在之前的位置有一个字母数字
  • (?=[a-z0-9]):断言我们在下一个位置有一个字母数字

var inputs = [`TestTEST!@#$%^&*()_+{}|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499488;TestTEST!@#$%^&*()_+{}|\":?><,.;'[]\\=-this is a long text.test 123455899949949494949499499`,
    'a1;b2;c3;d4;e5;', '#;1', 'a;b;c;d;e', '1;2;3;4;5',
    '!@#\$%^&*()_+;!@#\$%^&*()_+;']
    
const re = /(?<=[a-z0-9]);(?=[a-z0-9])/i;

for (var i=0; i<inputs.length; i++)
   console.log(inputs[i].split(re))

然而,在较旧的浏览器中,Javascript不支持lookbehind。您可以使用捕获组而不是lookbehind来捕获必须是字母数字的前一个字符和一个肯定的前瞻,以断言分号后面跟着一个字母数字字符。

您可以使用:

var arr = str.split(/(.*?[a-z0-9]+);(?=[a-z0-9])/i).filter(Boolean)

代码演示:

var inputs = [`TestTEST!@#$%^&*()_+{}|\":?><,./;'[]\\=-this is a long text.test 123455899949949494949499488;TestTEST!@#$%^&*()_+{}|\":?><,.;'[]\\=-this is a long text.test 123455899949949494949499499`,
    'a1;b2;c3;d4;e5;', '#;1', 'a;b;c;d;e', '1;2;3;4;5',
    '!@#\$%^&*()_+;!@#\$%^&*()_+;']

var re = /(.*?[a-z0-9]+);(?=[a-z0-9])/i;

for (var i=0; i<inputs.length; i++)
   console.log(inputs[i].split(re).filter(Boolean));

使用filter(Boolean)过滤掉输出数组中的空结果。

答案 2 :(得分:1)

你会看到我在第一个数组中使用'#'作为要测试的垃圾字符,但应该适用于任何非字母数字字符。我根据你的评论假设你想要删除超过1个字符的所有字母数字字符串,这就是我试图做的事情。

var strs = ["a;bbbb;c;dd;#","1;2;33;4;5","!@#$%^&*()_+;!@#$%^&*()_+;"]

    for (var i = 0; i < strs.length; i++) {
      var str = strs[i].split(';');
      for (var j=0; j < str.length; j++) {
       var chars = str[j];
         if (chars.match(/[^A-Za-z\d]{2}/g)) {
          console.log('this is our special character string '+strs[i]);
          break;
        }
       
       if (chars.length > 1 ) continue;
       var output = chars.split(/[^\s]([a-zA-Z\d]{1})/);
        for (var e = 0; e < output.length; e++) {
        var value = output[e];

        if (value && value.match(/[A-Za-z\d]/g)) {
             console.log(value); 
        }         
      }
     }
    }