regexp选择并验证逗号分隔字符串的字符串

3bygqnnd  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(97)

Maven,我卡住了。我有一个字符串,其中包含由逗号分隔的各种模式。我需要验证两件事:(1)每个模式匹配零个或多个逗号分隔的字符串,以及(2)没有不匹配模式的字符串。每个字符串元素都用逗号分隔(没有别的),逗号后面可能有尾随空格(我知道我可以在验证步骤之前用替换来删除!)
迄今采取的步骤:
将字符串(按逗号)拆分为字符串元素数组要匹配的字符串模式:

(a) single numbers e.g. 1,2,300,5,7,80 (up to 4 digits) etc.   
(b) ranges e.g. 1-5, 23-45,45-23 (up to 4 digits either side) etc.
(c) r1-r50, r45-r4 (up to 4 digits)
(d) 1-z, z-100
(e) string which contains one of two patterns 12-34:odd and 34-4:even

字符串
我想要的是通过对原始字符串进行regexp比较,将模式匹配字符串组直接拉入数组,而不是将其拆分为数组(当然可以!)
那么,我需要什么正则表达式来过滤每个潜在的模式,并通过查看原始字符串来提取匹配的字符串元素呢?
这并不紧急,因为我有一个将它们拆分为元素的工作版本,但作为学习练习,我不清楚如何构造regexp并将其应用于带逗号的字符串。
延伸问题:如何快速识别不遵循一个或多个模式的字符串元素。
谢谢
到目前为止,我得到的是:

(a) ^\d{0,5}*$
(b) ^\d{0,5}-\d{0,5}*$
(c) (?:z)
(d) (?:r)
(e) (?:odd|even)


所以代码提取:

$reg1 = '^\d{0,5}*$'    
$reg2 = '^\d{0,5}-\d{0,5}*$'
$reg3 = '(?:z)'           
$reg4 = '(?:r)'           
$reg5 = '(?:odd|even)'


这适用于拆分为数组元素的字符串。

$phase1 = $rangearray | Select-String $reg1 -AllMatches | %{$_.Line} | sort # single numbers only
if($phase1.count -gt 0) { $Allpages[0].Single = $true; $Allpages[1].Single = @($phase1); }

$phase1 = $rangearray | Select-String $reg2 -AllMatches | %{$_.Line} # number ranges
if($phase1.count -gt 0) { $Allpages[0].Ranged = $true; $Allpages[1].Ranged = {$phase1}.Invoke(); }

$phase1 = $rangearray | Select-String $reg3 -AllMatches | %{$_.Line} # max range option z
if($phase1.count -gt 0) { $Allpages[0].Z = $true; $Allpages[1].Z = @($phase1); }

$phase1 = $rangearray | Select-String $reg5 -AllMatches | %{$_.Line} # odds and evens
if($phase1.count -gt 0) { $Allpages[0].OddEven = $true; $Allpages[1].OddEven = @($phase1); }


这个函数传递一个字符串。该字符串的示例如下:

$range = '1-2,12-14,27-25,300-270,r10-r15,450-470:odd'
$range = '4, 2, 5, 14-12,16-18,20-19,r3-r1,285-290,r7-r4,388-z'

b1zrtrql

b1zrtrql1#

我建议使用带有-Regex开关的switch语句,利用它对数组值输入进行重排序的能力,以及它产生多个输出的能力,这些输出可以收集在一个数组中:

# Sample input string.
$range = ' 4, 2, 5, 14-12,16-18,20-19,r3-r1,285-290,r7-r4,388-z, 450-470:odd, WRONG'

[string[]] $validTokens = 
  switch -Regex (($range -split ',').Trim()) {
    '^\d{1,4}(?:-\d{1,4}(:(?:odd|even))?)?$' { $_; continue } # e.g. '4', '14-12', '450-470:odd'
    '^r\d{1,4}-r\d{1,4}$' { $_; continue } # e.g. 'r3-r1'
    '^z-\d{1,4}$' { $_; continue } # e.g. '388-z'
    '^\d{1,4}-z$' { $_; continue } # e.g. '1-z'
    default { Write-Warning "Doesn't match any expected pattern: '$_'" }
  }

字符串

  • ($range -split ',').Trim()通过,拆分$range字符串,并从每个结果元素中删除周围的空白。
  • 然后,针对构成分支条件的正则表达式对每个元素进行测试,如果它们匹配一个,则通过($_),然后处理继续到下一个元素(continue)。
  • 只有当所有正则表达式都不匹配时,才会到达default分支。

若要处理多个范围,请将上述内容包含在foreach语句或ForEach-Object调用中。

mkshixfv

mkshixfv2#

这是一个参考。

  • ".(a)单一数字,例如1、2、300、5、7、80(最多4位数字)等."*

考虑到这一点,检查最后。

\d{1,4}

字符串

  • "...(B)范围,例如1-5、23- 45、45 -23(每侧最多4位)等。

(e)包含两种模式之一的字符串12-34:奇数和34-4:偶数."*

\d{1,4}-\d{1,4}(?::odd|even)?

  • "..(c)r1-r50,r45-r4(最多4位数)."*
r\d{1,4}-r\d{1,4}

  • ".(d)1-z,z-100."*
\d{1,4}-z|z-\d{1,4}

  • "...那么我需要什么正则表达式来过滤每个潜在的模式,并通过查看原始字符串来提取匹配的字符串元素?..."*

合并这些;这里是一个 * 匹配模式 *。

(?:r\d{1,4}-r\d{1,4}|\d{1,4}-\d{1,4}(?::odd|even)?|\d{1,4}-z|z-\d{1,4})|\d{1,4}

  • "...我需要验证两件事:(1)每个模式匹配零个或多个逗号分隔的字符串,(2)没有不匹配模式的字符串。

您需要先验证 string
我假设您可以使用^$语法来Assert字符串的开始和结束。
这里有一个例子。
如果 p 是上面的模式,则等于^p(?:,\s*p)*$

^(?:(?:r\d{1,4}-r\d{1,4}|\d{1,4}-\d{1,4}(?::odd|even)?|\d{1,4}-z|z-\d{1,4})|\d{1,4})(?:,\s*(?:(?:r\d{1,4}-r\d{1,4}|\d{1,4}-\d{1,4}(?::odd|even)?|\d{1,4}-z|z-\d{1,4})|\d{1,4}))*$


从这里开始,使用初始模式来 * 匹配 * 每个值。

g52tjvyc

g52tjvyc3#

正则表达式的描述:

((?:r\d{1,4}-r\d{1,4})|(?:\d{1,4}-\d{1,4}:(?:odd|even))|(?:z-\d{1,4})|(?:\d{1,4}-z)+|(?:\d{1,4}-\d{1,4})|(?:\d){1,4})(?:,|\s|$)

字符串
在应用Regex之前,不需要对字符串进行操作。您可以直接应用此regex以获取所需的有效值。
请根据需要尝试添加/删除/修改最后一部分(?:,|\s|$)

[1]: A numbered capture group. [(?:r\d{1,4}-r\d{1,4})|(?:\d{1,4}-\d{1,4}:(?:odd|even))|(?:z-\d{1,4})|(?:\d{1,4}-z)+|(?:\d{1,4}-\d{1,4})|(?:\d){1,4}]
      Select from 6 alternatives
          Match expression but don't capture it. [r\d{1,4}-r\d{1,4}]
              r\d{1,4}-r\d{1,4}
                  r
                  Any digit, between 1 and 4 repetitions
                  -r
                  Any digit, between 1 and 4 repetitions
          Match expression but don't capture it. [\d{1,4}-\d{1,4}:(?:odd|even)]
              \d{1,4}-\d{1,4}:(?:odd|even)
                  Any digit, between 1 and 4 repetitions
                  -
                  Any digit, between 1 and 4 repetitions
                  :
                  Match expression but don't capture it. [odd|even]
                      Select from 2 alternatives
                          odd
                              odd
                          even
                              even
          Match expression but don't capture it. [z-\d{1,4}]
              z-\d{1,4}
                  z-
                  Any digit, between 1 and 4 repetitions
          Match expression but don't capture it. [\d{1,4}-z], one or more repetitions
              \d{1,4}-z
                  Any digit, between 1 and 4 repetitions
                  -z
          Match expression but don't capture it. [\d{1,4}-\d{1,4}]
              \d{1,4}-\d{1,4}
                  Any digit, between 1 and 4 repetitions
                  -
                  Any digit, between 1 and 4 repetitions
          Match expression but don't capture it. [\d], between 1 and 4 repetitions
              Any digit
  Match expression but don't capture it. [,|\s|$]
      Select from 3 alternatives
          ,
          Whitespace
          End of line or string

相关问题