正则表达式从模式生成多个IP地址

时间:2016-07-13 17:35:04

标签: regex powershell

我有一个文本文件,其中包含如下定义的IP地址范围:

10.30.8.4
10.30.6.[10:12]
10.30.[8:9].4
[10:11].30.12.23
[10:11].[28:29].[11:12].[22:23]

通过使用正则表达式解析它,我希望输出为

10.30.8.4
10.30.6.10
10.30.6.11
10.30.6.12
10.30.8.4
10.30.9.4
10.30.12.23
11.30.12.23
10.28.11.22
10.28.11.23
10.28.12.22
10.28.12.23
10.29.11.22
10.29.11.23
10.29.12.22
10.29.12.23
11.28.11.22
11.28.11.23
11.28.12.22
11.28.12.23
11.29.11.22
11.29.11.23
11.29.12.22
11.29.12.23

这是我到目前为止所得到的

$ips = Get-Content C:\temp\hosts.txt
$regex = [regex] "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"

$regex.Matches($ips) | %{ $_.value }

这只获得第一个IP地址而不是其他地址

3 个答案:

答案 0 :(得分:2)

遗憾地说,但正则表达式完全是用于错误的工作工具,虽然可以使用正则表达式作为一个营养均衡的解决方案的一部分:

foreach ($line in (Get-Content D:\data.txt))
{
    if ($line -match ':') 
    {
            $Left, $Range, $Right = $line -split '\[(.*)\]'
            $start, $end = $Range -split ':'
            $start..$end |% { "$Left$_$Right" }
    } 
    else 
    {
        $line
    }
}

NB。 " IP地址范围定义如下"没有定义任何东西,它只是三个例子。我完全猜到了它应该是什么意思。因人而异。

编辑您的编辑:如果每个块可以是一个范围,则完全不同。我打破了一个函数,使每个项目都可迭代,直接数字保持为数字,或者范围扩展到范围内的所有项目。四个嵌套循环并不是那么糟糕,但我不想为IPv6做这个......

Function Get-ExpandedBlock {
    Param($block)
    # Takes an IP chunk, either a number '10' or a range '[10:12]'
    # Returns either the number: '10' or
    # a PowerShell range over the input range: 10,11,12

    if ($block -match ':') {
        $start, $end = $block.Trim('[]') -split ':'
        $start..$end
    } else {
        $block
    }
}

$fullList = foreach ($line in (Get-Content D:\data.txt)) {
    $a, $b, $c, $d = $line.Split('.')

    foreach ($w in Get-ExpandedBlock $a) {
     foreach ($x in Get-ExpandedBlock $b) {
      foreach ($y in Get-ExpandedBlock $c) {
       foreach ($z in Get-ExpandedBlock $d) {
           "$w.$x.$y.$z"
       }
      }
     }
    }
}

$fullList

答案 1 :(得分:0)

   List<String> resolveRange( String iprange )
   {
      List<String> ipList = new ArrayList<String>();
      if ( iprange.indexOf( "[" ) < 0 )
      {
         ipList.add( iprange );
      }
      else
      {
         String[] sections = iprange.split( "\\." );
         Object[] output = new Object[4];
         int count = 1;
         int index = 0;
         for ( String section : sections )
         {
            List<String> ips = resolve( section );
            count *= ips.size();
            output[index++] = ips;
         }

         ipList = new ArrayList<String>( count );
         List<String> section1 = (List<String>) output[0];
         List<String> section2 = (List<String>) output[1];
         List<String> section3 = (List<String>) output[2];
         List<String> section4 = (List<String>) output[3];

         for ( String first : section1 )
         {
            for ( String second : section2 )
            {
               for ( String third : section3 )
               {
                  for ( String four : section4 )
                  {
                     ipList.add( new StringBuilder().append( first ).append( "." ).append( second ).append( "." ).append( third ).append( "." ).append( four ).toString() );
                  }
               }
            }
         }
      }

      return ipList;
   }

   List<String> resolve( String section )
   {
      List<String> listString = new ArrayList<String>();

      if ( section.indexOf( "[" ) >= 0 )
         listString = parse( section );
      else
         listString.add( section );
      return listString;
   }

   List<String> parse( String rangeString )
   {
      String[] arr = rangeString.replaceAll( "[\\[\\]]", "" ).split( ":" );
      int start = Integer.valueOf( arr[0] );
      int end = Integer.valueOf( arr[1] );

      List<String> nums = new ArrayList<String>();
      while ( start <= end )
      {
         nums.add( String.valueOf( start++ ) );
      }

      return nums;
   }

答案 2 :(得分:-1)

一般来说,你不能使用正则表达式来处理这类问题,其中部分模式可能会有所不同,或者可能是那部分,在整个字符串上强制执行某些条件,例如,八位字节被替换为范围,OR THAT 八位字节由范围替换。它不会生长。

解决此问题的适当媒介是AWK。您可以识别五种模式原型中的任何一种:

范围“。”数字“。”数字“。”数字
数字“。”范围 ”。”数字“。”数字
数字“。”数字“。”范围 ”。”数字
数字“。”数字“。”数字“。”范围
数字“。”数字“。”数字“。”数字

并且,除了第五个之外,在“范围”隐式指定的值上循环以生成族中的所有地址,使用伪变量$ 1,$ 3,$ 5和/或$ 7适当引用到各个地址部分。