在引号之间找到字符串,但在冒号之前?

时间:2018-10-22 20:28:29

标签: regex powershell substring

我已经测试了各种示例,但似乎没有一个适合我。

给出这样的字符串:

"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}

是否可以使用RegEx来获取冒号前面的双引号中的字符串?在这种情况下,我只想要FOO,BAR,FIND,ME。没有其他值。

谢谢

5 个答案:

答案 0 :(得分:3)

您的输入对象只是有效JSON中缺少的{之一,因此,如果我们将其转换为这样的话...

$json = '{"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}}'

然后我们可以检索父节点(FOO)的名称,以及每个属性的名称。

$json = '{"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}}'
$objects = ConvertFrom-Json $json

($objects.PSobject.Properties) | % {
    $parent = $_.Name
    $childrenNames = $_.Value.PSObject.Properties | % {$_.Name}
    }
[pscustomobject]@{ParentColumn=$parent;ChildrensNames=$childrenNames}


ParentColumn ChildrensNames 
------------ -------------- 
FOO          {BAR, FIND, ME}

让我知道这是否可以使您朝正确的方向前进:)

答案 1 :(得分:1)

快速浏览一些示例可知,在PowerShell中可以执行以下操作:

$results = $data | Select-String '"([^"]+)":' -AllMatches

应在其中存储组号1(第一个和唯一的括号)

$results[0].Groups[1].Value
$results[1].Groups[1].Value
...

[^"]与任何非双引号字符匹配

答案 2 :(得分:1)

正则表达式[A-Z0-9]+(?=\"(?=:))适用于提供的示例字符串。

$string = '"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}'
$matches = ([regex]'[A-Z0-9]+(?=\"(?=:))').Matches($string)
$matches.value

$matches.value返回(作为数组):

FOO
BAR
FIND
ME

正则表达式说明

[A-Z0-9]-匹配A-Z0-9之间的任何字符

+-尽可能多地匹配

(?=...)-正向超前查询,仅在跟随超前查询中的特定字符时匹配。

\"-从字面上匹配字符"

:-从字面上匹配字符:

将它们放在一起,[A-Z0-9]+尽可能匹配A-Z0-9,并且(?=\"(?=:))仅在其后跟"然后是:时才匹配。 / p>

有关正则表达式的更多信息:https://regex101.com/r/PsKS6N/1/

答案 3 :(得分:1)

如果必须使用正则表达式来解决此问题,这是一个简洁的解决方案(PSv3 +):

[regex]::Matches(
  '"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}',
  '(?<=")[^"]+(?=":)'
).Value   # -> 'FOO', 'BAR', 'FIND', 'ME'

如果输入(有效地)是JSON ,请考虑使用基于ConvertFrom-Json的方法,如FoxDeploy's answer

这是该方法的概括,它通过遍历任意对象层次结构以报告其属性的平面列表的功能(不包括CLR运行时的属性(原始)类型)),其中是来自ConvertFrom-Json从JSON创建的自定义对象层次结构的输入

# Define the walker function:
# Get a flat list of all properties in a given object's hierarchy,
# excluding properties of instances of .NET runtime types (primitive types).
function get-PropertyList {
  param([object] $o)
  if ($null -eq $o) {
    # Nothing to do.
  # A collection of sorts (other than a string or dictionary (hash table)), recurse on its elements
  } elseif ($o -is [System.Collections.IEnumerable] -and $o -isnot [string] -and $o -isnot [System.Collections.IDictionary]) { 
    foreach ($osub in $o) { get-PropertyList $osub }
  # A primitive (runtime) type.
  } elseif ($o.GetType().FullName -in 'System.Boolean', 'System.SByte',  'System.Byte',  'System.Int16', 'System.UInt16', 'System.Int32', 'System.UInt32', 'System.Int64', 'System.UInt64', 'System.Single', 'System.Double', 'System.Decimal', 'System.DateTime', 'System.Char', 'System.String') {
    # Don't report a primitive type's properties (most don't have any, but [string] and [datetime] do)
  } else { # scalar, non-primitive object or a dictionary; enumerate its properties / entries
    $props = if ($o -is [System.Collections.IDictionary]) { $o.GetEnumerator() } else { $o.psobject.properties }
    foreach ($p in $props) {
      $p.Name
      foreach ($osub in $p.Value) { get-PropertyList $osub }
    }
  }
}

# Make the input string a JSON string.
$str = '"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}'
$json = '{' + $str + '}'

# Convert the JSON string to a custom-object hierarchy and let the walker
# function enumerate all of its properties as a flat list.
$json | ConvertFrom-Json | get-PropertyList # -> 'FOO', 'BAR', 'FIND', 'ME'

答案 4 :(得分:0)

这可能太脆弱了,但是它确实适用于您提供的有限示例... [咧嘴]

$InStuff = '"FOO":{"BAR":"0x507A","FIND":"DONTFINDME","ME":["0x3214"]}'

$InStuff -split ':' |
    Where-Object {$_ -match '"$'} |
    ForEach-Object {
        if ($_ -match ',')
            {
            $_.Split(',')[1]
            }
            else
            {
            $_
            }} |
    ForEach-Object {$_.Trim('{"')}

输出...

FOO
BAR
FIND
ME