使用正则表达式格式化包含uk邮政编码的字符串

时间:2012-05-22 11:16:24

标签: javascript regex

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

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

N1 3LD
EC1A 3AD
GU34 8RR

我有正确验证字符串的以下正则表达式,但我不确定如何使用正则表达式作为掩码将EC1A3AD格式化为EC1A 3AD / GU348RR到{{1} } / GU34 8RRN13LD

我的正则表达式是N1 3LD

谢谢

3 个答案:

答案 0 :(得分:13)

如果您使用正则表达式/^([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

答案 1 :(得分: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"]

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

答案 2 :(得分:0)

我使用上面@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>

插入符号&amp; set函数是直接从堆栈溢出的答案中获取的,我现在找不到它给用户信用。我会看看&amp;如果可以的话,用链接更新。

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

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