regex 将行和列区域转换为行和列数组

uinbv5nw  于 2023-01-06  发布在  其他
关注(0)|答案(1)|浏览(113)

我想把下面的范围转换成行和列的符号
示例输入和预期输出如下所示

Input is A1 => Then output is [0,1,0,1]
B1 = [0,1,1,2]
A2 = [1,2,0,1]
C2 = [1,2,2,3]
C12 = [11,12,2,3]
A1:B4 = [0,4,0,2]
C1:D11 = [0,11,2,4]
F32:H43 = [31,43,5,8]
C:F = [null,null,2,6]
30:38 = [29,38,null,null]
76:79 = [75,79,null,null]

AA1:AD15 = [0,15,26,30]

Z2:B1 = [null,null,null,null] or undefined //any invalid range
2:B1 = [null,null,null,null] or undefined //any invalid range
0:0 = [null,null,null,null] or undefined //any invalid range
4-2 = [null,null,null,null] or undefined //any invalid range
6-7d7 = [null,null,null,null] or undefined //any invalid range

The general formula
[startrow-1,endrow,startcol-1,endcol]

30:38 = [startrow-1,endrow,null,null]
76:79 = [startrow-1,endrow,null,null]
C:F = [null,null,2,6]

A1
can also be written as 
A1:A1 = [0,1,0,1]

C12
can also be written as 
C12:C12 = [11,12,2,3]

我的代码适用于这些

A10:B10 //already works

A:B10 //not working so far 

A10:B //not working so far

A:B //not working so far

10:10 //not working so far
<!DOCTYPE html>
<html>

<body>
<script>
function fromA1Notation(cell) {
    var i, l, chr,
        sum = 0,
        A = "A".charCodeAt(0),
        radix = "Z".charCodeAt(0) - A + 1;

    if (typeof cell !== 'string' || !/^[A-Z]+$/.test(cell)) {
        throw new Error("Expected column label");
    }

    for (i = 0, l = cell.length; i < l; i++) {
        chr = cell.charCodeAt(i);
        sum = sum * radix + chr - A + 1
    }

    return sum;
}

var input = "A1:B20";

if (input.length > 0 && input.match(/[A-Z]+[0-9]+:[A-Z]+[0-9]+/i) != null) {
    var matched = input.match("([A-Za-z]+)([0-9]+):([A-Za-z]+)([0-9]+)");
console.log(JSON.stringify(matched))
    if (matched != null) {
        a1range = {
            a1not: input,
            c1: (fromA1Notation(matched[1].toUpperCase()) - 1),
            r1: (matched[2] - 1),
            c2: fromA1Notation(matched[3].toUpperCase()),
            r2: matched[4]
        };

        if (a1range.c1 >= a1range.c2 || a1range.c1 >= a1range.c2) {
            a1range = undefined;
        }
        console.log(a1range)
    }
}
        console.log(a1range)

</script>
</body>

</html>
holgip5t

holgip5t1#

下面是一个解决方案:

  • 将“A1”模式转换为“A1:A1”
  • 匹配列,num,“:”,列,num
  • 将col字母转换为基于1的索引
  • 执行无效范围检查
  • 已将起始行和起始列索引修复为基于零
function A2N (str) {
  return str.split('').reduce((acc, char, idx) => {
    return acc += char.charCodeAt(0) - 65 + (idx * 26);
  }, 1);
}

[ 'A1', 'B1', 'A2', 'C:F', 'A10:B10', 'A:B10', 'A10:B', 'A:B', '10:10', 'AA1', 'AAA1', 'A', '1', 'B', '20', 'Z9:A1', '@'
].forEach(str => {
  let parts = str
    .replace(/^(\w+)$/, '$1:$1') // turn 'A1' into 'A1:A1'
    .match(/^([A-Z]*)([0-9]*)(?::([A-Z]*)([0-9]*))?$/);
  let result = [ null, null, null, null ];
  if(parts) {
    result = [
      parts[2] ? Number(parts[2]) : null,
      parts[4] ? Number(parts[4]) : null,
      parts[1] ? A2N(parts[1]) : null,
      parts[3] ? A2N(parts[3]) : null
    ];
    if(result[0] && result[1] && result[0] > result[1]) {
      // invalid range
      result[0] = null;
      result[1] = null;
    }
    if(result[2] && result[3] && result[2] > result[3]) {
      // invalid range
      result[2] = null;
      result[3] = null;
    }
    if(result[0]) {
      // zero-based start row
      result[0]--;
    }
    if(result[2]) {
      // zero-based start col
      result[2]--;
    }
  }
  console.log(str, '==>', result);
});

相关问题