6

如何使用 Javascript 格式化字符串以匹配正则表达式?

我使用的英国邮政编码可以匹配以下任何一个

N1 3LD
EC1A 3AD
GU34 8RR

我有以下正则表达式可以正确验证字符串,但我不确定如何使用正则表达式作为掩码来格式化EC1A3ADto EC1A 3AD/ GU348RRto GU34 8RR/ N13LDto N1 3LD

我的正则表达式是/^[A-Za-z]{1,2}[0-9A-Za-z]{1,2}[ ]?[0-9]{0,1}[A-Za-z]{2}$/

谢谢

4

3 回答 3

17

如果您使用正则表达式/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(\d[A-Z]{2})$/,您可以提取邮政编码的两个部分并用中间空格重新组合它们。

var list = ['N13LD', 'EC1A3AD', 'GU348RR'];

for (var i = 0; i < list.length; i++) {
  var parts = list[i].match(/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(\d[A-Z]{2})$/);
  parts.shift();
  alert(parts.join(' '));
}

输出

N1 3LD
EC1A 3AD
GU34 8RR
于 2012-05-22T11:59:20.477 回答
1

在由可选空格分隔的位周围放置大括号:

/^([A-Za-z]{1,2}[0-9A-Za-z]{1,2})[ ]?([0-9]{0,1}[A-Za-z]{2})$/

但是我认为正则表达式是错误的......上面的正则表达式将“N13LD”拆分为“N13”,“LD”。

我怀疑错误的部分是{0,1}两个尾随字母之前 - AFAIK 必须正好是一个数字:

var re = /^([A-Z]{1,2}[\dA-Z]{1,2})[ ]?(\d[A-Z]{2})$/i; // case insensitive

分组允许string.match(regexp)函数返回一个结果,其中包括每个匹配组的条目:

> "N13LD".match(re);
["N13LD", "N1", "3LD"]

> "GU348RR".match(re);
["GU348RR", "GU34", "8RR"]

> "EC1A3AD".match(re);
["EC1A3AD", "EC1A", "3AD"]

要获得结果,只需使用简单的字符串连接将每个结果中的第二个和第三个元素连接在一起。

于 2012-05-22T11:22:24.217 回答
1

我使用上面@borodin 的出色答案创建了一个英国邮政编码即用型格式化程序。请注意,这不会验证邮政编码,只是在用户键入时根据 borodin 的正则表达式对其进行格式化。

var txtPc = $("#postcode");
var outputCount = 0;
var jigCount = 0;
var postcodePauseTime = 500;

txtPc.on("keydown", function(e) {
  var keyCode = e.which;

  var key = String.fromCharCode(keyCode);
  var isAlphaNumeric = //key.match(/^[a-z0-9]+$/i);
    (
      (keyCode >= 65 && keyCode <= 90) ||
      (keyCode >= 48 && keyCode <= 57) ||
      ([189, 190, 8, 46, 9].indexOf(keyCode) > -1) ||
      (keyCode >= 35 && keyCode <= 40)
    );

  return !!isAlphaNumeric;
});
// handle click and add class
txtPc.on("keyup", function(e) {
  PostcodeCalculateFormat(txtPc);
});

txtPc.on("blur", function() {
  PostcodeCalculateFormat(txtPc);
});

function PostcodeCalculateFormat(txtPc) {
  (function(index, txtPc) {
    setTimeout(function() {
      //prevent interferance from other keypresses by returning out of this closure
      if (index != jigCount) return;
      var isFocused = ($('#' + txtPc.attr('id') + ':focus')[0] == document.activeElement);
      var postcodeText = txtPc.val().toUpperCase(); /// + key;
      var origSpacePos = postcodeText.indexOf(" ");
      postcodeText = postcodeText.replace(/[\W_]+/g, "");
      var parts = postcodeText.match(/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(\d[A-Z]{2})$/i);
      //if unable to match the lot, try the first part only with less strict reg
      if (!parts)
        parts = postcodeText.match(/^([A-Z]{1,2}\d{1,2}[A-Z]?)\s*(.*)$/i);
      if (parts) {
        var caretPos = 0;
        if (isFocused)
          caretPos = getCaretPosition(txtPc[0]).start;
        parts.shift();
        var newVal = parts.join(' ');
        if (newVal == txtPc.val())
          return;
        output(newVal);
        txtPc.val(newVal);
        var spacePos = newVal.indexOf(" ");
        if (isFocused) {
          if (caretPos >= spacePos && origSpacePos == -1)
            caretPos++;

          setCaretPosition(txtPc[0], caretPos, caretPos);
        }
      }
    }, postcodePauseTime);
  }(++jigCount, txtPc));
}

function output(str) {
  $("#listOutput").prepend("<li>[" + (++outputCount) + "] " + str + "</li>");
}

function getCaretPosition(ctrl) {
  // IE < 9 Support
  if (document.selection) {
    ctrl.focus();
    var range = document.selection.createRange();
    var rangelen = range.text.length;
    range.moveStart('character', -ctrl.value.length);
    var start = range.text.length - rangelen;
    return {
      'start': start,
      'end': start + rangelen
    };
  }
  // IE >=9 and other browsers
  else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
    return {
      'start': ctrl.selectionStart,
      'end': ctrl.selectionEnd
    };
  } else {
    return {
      'start': 0,
      'end': 0
    };
  }
}


function setCaretPosition(ctrl, start, end) {
  // IE >= 9 and other browsers
  if (ctrl.setSelectionRange) {
    ctrl.focus();
    ctrl.setSelectionRange(start, end);
  }
  // IE < 9
  else if (ctrl.createTextRange) {
    var range = ctrl.createTextRange();
    range.collapse(true);
    range.moveEnd('character', end);
    range.moveStart('character', start);
    range.select();
  }
}
body {
  background: silver;
  padding: 20px;
  font-family: Helvetica;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>

<div>Sample postcodes to type: 'BT92PE', 'EC1A3AD', 'GU348RR', 'N13LD'</div>

<div>
  Postcode: <input id="postcode" style="text-transform: uppercase; " />
</div>

<!-- for troubleshooting -->
<ul id="listOutput"></ul>

插入符号获取和设置函数直接取自堆栈溢出答案,我现在找不到给用户信用。如果可以的话,我会查看并更新链接。

这可以满足我的所有需求,但这不是一个非常优雅的解决方案。我很高兴有人在这方面进行改造、增强或改进。我想看看结果。

未来的改进:如果插入符号在空格之后,退格键应该一键删除空格和它之前的字母数字字符。(如果插入符号位于空格之前,则删除按钮的想法相同。)

于 2018-06-05T19:57:49.810 回答