5

我需要一个正则表达式来匹配一个值,其中每个字符可以是从 0 到 9 的数字或空格。该值必须恰好包含 11 位数字。

例如,它应该匹配格式为“012 345 678 90”或“01234567890”的值。

谁能帮我解决这个问题?

4

10 回答 10

23

为了将来可能会发现这一点的其他澳大利亚开发人员:

^(\d *?){11}$

匹配 11 个数字,每个数字后有零个或多个空格。

编辑:

正如@ElliottFrisch 所提到的,ABN 也有一个用于正确验证的数学公式。使用正则表达式来正确验证 ABN 将非常困难(或不可能) - 尽管上述正则表达式至少将匹配 11 位数字和间距。如果您在进行实际验证,那么在这种情况下,正则表达式可能不适合您。

进一步阅读:

https://abr.business.gov.au/Help/AbnFormat

这是一个 PHP 实现:

http://www.clearwater.com.au/code

从上面的页面复制的代码,以防有一天它变得不可用:

//   ValidateABN
//     Checks ABN for validity using the published 
//     ABN checksum algorithm.
//
//     Returns: true if the ABN is valid, false otherwise.
//      Source: http://www.clearwater.com.au/code
//      Author: Guy Carpenter
//     License: The author claims no rights to this code.  
//              Use it as you wish.

function ValidateABN($abn)
{
    $weights = array(10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19);

    // strip anything other than digits
    $abn = preg_replace("/[^\d]/","",$abn);

    // check length is 11 digits
    if (strlen($abn)==11) {
        // apply ato check method 
        $sum = 0;
        foreach ($weights as $position=>$weight) {
            $digit = $abn[$position] - ($position ? 0 : 1);
            $sum += $weight * $digit;
        }
        return ($sum % 89)==0;
    } 
    return false;
}

还有一个我在这里找到的javascript:

http://www.mathgen.ch/codes/abn.html

于 2013-02-28T11:44:56.773 回答
4

参考旧死链接:http : //www.ato.gov.au/businesses/content.asp? doc=/content/ 13187.htm &pc=001/003/021/002/001&mnu=610&mfp=001/003&st=&cy= 1

确认 ABN

以下公式可用于验证分配给您的 ABN 或验证发给您处理的企业的 ABN。

要验证 ABN:
从第一个(左)数字中减去 1,得到一个新的 11 位数字 将这个新数字中的每个数字乘以其权重因子 将得到的 11 个乘积相加。
将总数除以 89,注意余数。
如果余数为零,则该数字有效。

数字位置
1 2 3 4 5 6 7 8 9 10 11

重量
10 1 3 5 7 9 11 13 15 17 19

例如,检查 ABN 53 004 085 616 的有效性

5 3 0 0 4 0 8 5 6 1 6

从第一个(左)数字减去 1 得到新数字 4 3 0 0 4 0 8 5 6 1 6

应用加权因子 10 1 3 5 7 9 11 13 15 17 19

(4x10)+(3x1)+(0x3)+(0x5)+(4x7)+(0x9)+(8x11)+(5x13)+(6x15)+(1x17)+ (6x19) 40+3+0+0 +28+0+88+65+90+17+114

445/89 = 5 余数 0

余数为零,因此该数字有效。

这是一个 C# 验证:

public static bool ValidateABN(string abn)
{
    bool isValid = false;
    int[] weight = { 10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
    int weightedSum = 0;

    //ABN must not contain spaces, comma's or hypens
    abn = StripNonDigitData(abn);

    //ABN must be 11 digits long  
    if (!string.IsNullOrEmpty(abn) & Regex.IsMatch(abn, "^\\d{11}$"))
    {
        //Rules: 1,2,3  
        for (int i = 0; i <= weight.Length - 1; i++)
        {
            weightedSum += (int.Parse(abn[i].ToString()) - ((i == 0 ? 1 : 0))) * weight[i];
        }
        //Rules: 4,5  
        return ((weightedSum % 89) == 0);
    }
    return isValid;
}

public static string StripNonDigitData(string input)
{
    StringBuilder output = new StringBuilder("");
    foreach (char c in input)
    {
        if (char.IsDigit(c))
        {
            output.Append(c);
        }
    }
    return output.ToString();
}

和一个 VB.Net 验证:

Public Shared Function ValidateABN(ByVal abn As String) As Boolean
    Dim isValid As Boolean = False
    Dim weight() As Integer = {10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
    Dim weightedSum As Integer = 0

    'ABN must not contain spaces, comma's or hypens
    abn = StripNonDigitData(abn)

    'ABN must be 11 digits long  
    If Not String.IsNullOrEmpty(abn) And Regex.IsMatch(abn, "^\d{11}$") Then
        'Rules: 1,2,3  
        For i As Integer = 0 To weight.Length - 1
            weightedSum += (Integer.Parse(abn(i).ToString()) - (IIf(i = 0, 1, 0))) * weight(i)
        Next
        'Rules: 4,5  
        Return ((weightedSum Mod 89) = 0)
    End If
    Return isValid
End Function

Public Shared Function StripNonDigitData(ByVal input As String) As String
    Dim output As New StringBuilder("")
    For Each c As Char In input
        If Char.IsDigit(c) Then
            output.Append(c)
        End If
    Next
    Return output.ToString
End Function
于 2017-03-08T00:58:43.113 回答
3
// return false if not correct AU vat format
function ABNValidation (val) {
    val = val.replace(/[^0-9]/g, '');
    let weights = new Array(10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19);
    if (val.length === 11) { 
        let sum = 0;
        weights.forEach(function(weight, position) {
            let digit = val[position] - (position ? 0 : 1);
            sum += weight * digit;
        });
        return sum % 89 == 0;
    }
    return false;
}
于 2017-07-19T08:57:09.997 回答
2

另一个 JavaScript 版本:

/**
 * validate ABN
 * @param {string} abn
 * @return {boolean} is ABN number valid
 *    
 * 0. ABN must be 11 digits long
 * 1. Subtract 1 from the first (left) digit to give a new eleven digit number         
 * 2. Multiply each of the digits in this new number by its weighting factor         
 * 3. Sum the resulting 11 products         
 * 4. Divide the total by 89, noting the remainder         
 * 5. If the remainder is zero the number is valid  
 */
var validateABN = function(abn){

    var isValid = true;

    //remove all spaces
    abn = abn.replace(/\s/g, '');

    //0. ABN must be 11 digits long
    isValid &= abn && /^\d{11}$/.test(abn);

    if(isValid){

        var weightedSum = 0;
        var weight = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19];

        //Rules: 1,2,3  
        for (var i = 0; i < weight.length; i++) {
            weightedSum += (parseInt(abn[i]) - ((i === 0) ? 1 : 0)) * weight[i]; 
        }

        //Rules: 4,5                 
        isValid &= ((weightedSum % 89) === 0);
    }

    return isValid;
};

//tests
console.log(validateABN('51824753556'));
console.log(validateABN('51 824 753 556'));
console.log(validateABN('51824744556'));
于 2017-10-30T08:14:46.887 回答
1

你读过正则表达式吗?这很简单。

^[0-9 ]+$
于 2013-01-05T18:08:15.603 回答
1

对于那些使用 AngularJS 的人,我编写了一个指令来进行 ABN 验证:

var app = angular.module("demoapp", ["input-abn-directive"]);

<input type="abn" name="inputAbn" ng-model="modelAbn">

https://github.com/jasadams/input-abn-directive

于 2014-04-25T21:05:20.540 回答
0

JavaScript 版本:

function checkABN(str) {
    if (!str || str.length !== 11) {
        return false;
    }
    var weights = [10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
        checksum = str.split('').map(Number).reduce(
        function(total, digit, index) {
            if (!index) {
                digit--;
            }
            return total + (digit * weights[index]);
        },
        0
    );

    if (!checksum || checksum % 89 !== 0) {
        return false;
    }

    return true;
}
于 2015-09-17T07:53:30.810 回答
0

回答问题

很多答案将包括正则表达式[0-9]{11}或类似的,这对于大多数情况来说已经足够了,但是没有一个答案考虑到 ABN 不能以零开头的事实。

可用于确定 ABN 的最简单的正则表达式是:^\s*[1-9](\s*\d){10}\s*$.

标准格式

标准数字格式是 2,3,3,3 位分组模式,前两位数字构成校验位,后 9 位是实际标识符。

用于专门检查此格式(带或不带空格)的正则表达式是^[1-9]\d(\s?\d{3}){3}$.

number_format使用 PHP函数可以很容易地模仿这种格式。

number_format( '12123123123', 0, '', ' ' ) === '12 123 123 123';

实际验证

与实际验证相关的任何其他答案都应该大部分有效,但不是 100%,除非有额外的检查以确保数字不以零开头。扩展当前评分最高的答案,只需要进行一项额外的检查。

if ( strlen( $abn ) === 11 && $abn[0] > 0 ) { // or $abn > 9999999999
    // ...
}
于 2019-02-05T08:37:35.867 回答
0

已测试 ABN Javascript 实现

这些是有效的ABN

  • 33 051 775 556 应该可以
  • 14 069 979 460 应该可以
  • 24 302 976 253 应该可以

这些是无效的ABN:

  • 65 065 987 968 应该失败
  • 12 345 678 965 应该失败
  function checkABN(value) {
      let weights = new Array(10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19);
      let abn = value.replace(/\D/g, ''); // strip non numeric chars
      if (abn.length != 11) {
          return false;
      }
      let abnFirstDigit = parseInt(abn.charAt(0)) - 1; //subtract 1 from first digit
      abn = abnFirstDigit + abn.substring(1); // replace first digit with the substracted value

      let total = 0;
      for (let i = 0; i < 11; i++)
          total += weights[i] * abn.charAt(i);

      if (total == 0 || total % 89 != 0) {
          return false;
      } else {
          return true;
      }
  }

来自http://www.mathgen.ch/codes/abn.html的那个 有问题,它不允许 14 069 979 460(应该是有效的)

于 2019-03-01T00:19:16.483 回答
0

SQL Server 解决方案 - 在单个案例语句中

如其他答案中所述,单个正则表达式不太可能验证 ABN。下面的case语句可以在 Microsoft SQL Server 中用于验证 ABN。您可能希望在包含 ABN 字段的表上创建一个持久计算列。根据下面的评论,如果您返回整数而不是文本描述,那么您可以使用这样的字段进行相对简单的比较:

  • 1 = 有效
  • 0 = 无效(长度错误)
  • -1 = 无效(模式检查失败)

允许您使用以下表达式:

  • where abnValid = 1 -- match all valid records
  • where abnValid < 1 -- match all invalid records

下面验证 ABN 的逻辑基于 Jeremy Thompson 的回答。下面的语句冗长且效率低下 - 因此它适合单个case语句,以便您可以将它与持久计算列一起使用 - 这意味着性能影响将在更新时,而不是在选择时。它假设您的 abnColumn 是基于字符的 -cast如果您使用的是数字类型,请添加显式。它会忽略源数据中的空格字符,并假定 ABN 的第一个数字不为零。

    case 
        when len(ltrim(rtrim(replace(abnColumn,' ','')))) <> 11 then 'Wrong length' -- or perhaps 0
        when
        (
            ((try_cast(left(ltrim(rtrim(replace(abnColumn,' ',''))),1) as int)-1)*10) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),10),1) as int)*1) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),9),1) as int)*3) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),8),1) as int)*5) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),7),1) as int)*7) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),6),1) as int)*9) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),5),1) as int)*11) +
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),4),1) as int)*13) + 
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),3),1) as int)*15) + 
            (try_cast(left(right(ltrim(rtrim(replace(abnColumn,' ',''))),2),1) as int)*17) +
            (try_cast(right(ltrim(rtrim(replace(abnColumn,' ',''))),1) as int)*19)
        ) %89 <> 0 then 'Check pattern fail' -- or perhaps -1
        else 'Valid' -- or perhaps 1
    end as abnValidationCheck -- or perhaps abnValid
于 2020-07-07T05:23:19.567 回答