How to split and rebuild a string?

2019-06-05 21:13发布

问题:

I have the following code:

var input = "RE1467R31294998782";
var arr = input.split("");

and after executing it I get:

R,E,1,4,6,7,R,3,1,2,9,4,9,9,8,7,8,2

after that goes the following code:

arr2[0] = arr[0]+arr[1]; 
arr2[1] = arr[2]+arr[3];
arr2[2] = arr[4]+arr[5]; 
arr2[3] = arr[6]+arr[7];
arr2[4] = arr[8]+arr[9]; 
arr2[5] = arr[10]+arr[11];
arr2[6] = arr[12]+arr[13]; 
arr2[7] = arr[14]+arr[15];
arr2[8] = arr[16]+arr[17];

and the result is:

[RE,14,67,R3,12,94,99,87,82]

the end result should be the following:

RE-1467-R3-1294-99-8782

So, I would like to add a - every time the string changes from alphanumeric or >94 to numeric and <95.

But how do I do that? Any ideas?

Thanks for helping me out.

Edit: The string is always 18 chars or 11 chars long.

More examples:

1ZA2666W6831071503 to 1ZA2-66-6W-6831071503

1Z80A3109303081604 to 1Z-80-A3-109303081604

1Z80A3109603089504 to 1Z-80-A3-10-96-0308-95-04

回答1:

You could somewhat cleanly do it like this

var inputStr = 'RE1467R31294998782';
var splitRegex = /(\w{2})/g;
var pieces = inputStr.match(splitRegex);
var finalStr = [];
var prevDuet = '';

if (pieces && pieces.length > 0) {
    pieces.forEach(function(currentDuet) {
        if (!prevDuet) {
            finalStr.push(currentDuet);
        } else if (currentDuet > 94) {
            finalStr.push('-' + currentDuet);
        } else if ((isNaN(prevDuet) && !isNaN(currentDuet)) ||
                   (!isNaN(prevDuet) && isNaN(currentDuet))) {
            finalStr.push('-' + currentDuet);
        } else if (prevDuet > 94) {
            finalStr.push('-' + currentDuet);
        } else {
            finalStr.push(currentDuet);
        }
        prevDuet = currentDuet;
    });
}

alert(finalStr.join(''));



回答2:

And now for the ugliest answer possible:

var input = "RE1467R31294998782";
var arr = input.split(""), arr2 = [];
for(var i=0;i<Math.floor(input.length/2);i++){
    arr2[i] = arr[i*2]+arr[(i*2)+1];
}

var rebuilt = '';
for (var i = 0; i < arr2.length; i++) {
    rebuilt += arr2[i]+(i < arr2.length - 1 && (isUnit(arr2[i]) || isUnit(arr2[i + 1])))?'-':'';
}

function isUnit(part) {
    return String(part).match(/[A-Za-z]/g) || Number(part) > 94;
}

alert(rebuilt);

Even uglier but hopefully satisfies the condition in the other examples:

var input = "RE1467R31294998782";
var arr = input.split("");
var arr2 = [];
arr2[0] = arr[0]+arr[1]; 
arr2[1] = arr[2]+arr[3];
arr2[2] = arr[4]+arr[5]; 
arr2[3] = arr[6]+arr[7];
arr2[4] = arr[8]+arr[9]; 
arr2[5] = arr[10]+arr[11];
arr2[6] = arr[12]+arr[13]; 
arr2[7] = arr[14]+arr[15];
arr2[8] = arr[16]+arr[17];

var rebuilt = '';

for (var i = 0; i < arr2.length; i++) {
    var part = arr2[i],
        nextPart = arr2[i + 1];

    rebuilt += part;

    if (i < arr2.length - 1 && ((isAlpha(part) && !isAlpha(nextPart)) || (!isAlpha(part) &&  isAlpha(nextPart)) || isBigNum(part) || isBigNum(nextPart)))
        rebuilt += '-';
}

function isAlpha(part) {
    return String(part).match(/[A-Za-z]/g);
}

function isBigNum(part) {
    return Number(part) > 94;
}

alert(rebuilt);

(Sorry for lousy formatting to editor of my above code.)



回答3:

Unfortunately after the correction this alternative doesn't look nice at all, but works correctly:

var m = 0; // 0 = init, -1 = alpha-num, 1 = numeric < 95, 2 = numeric > 94
"RE1467R31295998782".replace(/[A-Z0-9]{2}/g, function(a) {
  if (isNaN(a)) {
    if (m == 1 || m == 2)
      a = '-' + a;
    m = -1;
  } else {
    if (parseInt(a) > 94) {
      if (m != 0)
        a = '-' + a;
      m = 2;
    } else {
      if (m == 2 || m == -1)
        a = '-' + a;
      m = 1;
    }
  }
  return a;
});

jsfiddle