Группировка Regex в Ruby - PullRequest
0 голосов
/ 29 мая 2011

Образец текста

    outline: 4 0
      corner: 1 347980000 -2540000 0
      corner: 2 347980000 -20320000 0
      corner: 3 482600000 -20320000 0
      corner: 4 482600000 -2540000 0

    outline: 4 1
      corner: 1 0 -2540000 0
      corner: 2 345440000 -2540000 0
      corner: 3 345440000 -20320000 0
      corner: 4 0 -20320000 0

    outline: 8 2
      corner: 1 0 0 0
      corner: 2 0 35560000 0
      corner: 3 53340000 35560000 0
      corner: 4 53340000 76200000 0
      corner: 5 449580000 76200000 0
      corner: 6 449580000 30226000 0
      corner: 7 482600000 30226000 0
      corner: 8 482600000 0 0

    outline: 4 3
      corner: 1 0 38100000 0
      corner: 2 50800000 38100000 0
      corner: 3 50800000 76200000 0
      corner: 4 0 76200000 0

    outline: 4 4
      corner: 1 482600000 76200000 0
      corner: 2 482854000 31750000 0
      corner: 3 450850000 31750000 0
      corner: 4 450850000 76200000 0

/^\s+corner:\s*(\d+)\s+(-?\d+)\s+(-?\d+)\s+(\d+)/m Захватывает все значения для углов.

/^\s*outline:\s*(\d+)\s+(\d+)$.*?\s+corner:\s*(\d+)\s+(-?\d+)\s+(-?\d+)\s+(\d+)/m Захватывает все контуры, но только первый угол каждого контура.

/^\s*outline:\s*(\d+)\s+(\d+)$.*?(^\s+corner:\s*(\d+)\s+(-?\d+)\s+(-?\d+)\s+(\d+)$).*?/m Делает то же самое, что и второй, но выглядит так:

4
0
corner: 1 347980000 -2540000 0
1
347980000
-2540000
0

Я пытаюсь заставить его охватить все очертания и связанные углы. Это явно не сгруппировано - Есть предложения?

Спасибо; -)

Ответы [ 2 ]

1 голос
/ 29 мая 2011

Поскольку количество требуемых снимков варьируется (возможно, без ограничений), вы не можете сделать это за одно регулярное выражение. String#scan пригодится в таком случае.

text.scan(/^\s*outline:\s*(\d+)\s+(\d+)\n(.*?)(?:\n\n|\z)/m)
.map{|a, b, corners| [a, b, corners.scan(/^\s+corner:\s*(\d+)\s+(-?\d+)\s+(-?\d+)\s+(\d+)/)]}

даст вам:

[["4", "0",
  [["1", "347980000", "-2540000", "0"],
   ["2", "347980000", "-20320000", "0"],
   ["3", "482600000", "-20320000", "0"],
   ["4", "482600000", "-2540000", "0"]]],
 ["4", "1",
  [["1", "0", "-2540000", "0"],
   ["2", "345440000", "-2540000", "0"],
   ["3", "345440000", "-20320000", "0"],
   ["4", "0", "-20320000", "0"]]],
 ["8", "2",
  [["1", "0", "0", "0"],
   ["2", "0", "35560000", "0"],
   ["3", "53340000", "35560000", "0"],
   ["4", "53340000", "76200000", "0"],
   ["5", "449580000", "76200000", "0"],
   ["6", "449580000", "30226000", "0"],
   ["7", "482600000", "30226000", "0"],
   ["8", "482600000", "0", "0"]]],
 ["4", "3",
  [["1", "0", "38100000", "0"],
   ["2", "50800000", "38100000", "0"],
   ["3", "50800000", "76200000", "0"],
   ["4", "0", "76200000", "0"]]],
["4", "4",
  [["1", "482600000", "76200000", "0"],
   ["2", "482854000", "31750000", "0"],
   ["3", "450850000", "31750000", "0"],
   ["4", "450850000", "76200000", "0"]]]]

Если вам нужны числа вместо строк,

text.scan(/^\s*outline:\s*(\d+)\s+(\d+)\n(.*?)(?:\n\n|\z)/m)
.map{|a, b, corners| [a.to_i, b.to_i, corners.scan(/^\s+corner:\s*(\d+)\s+(-?\d+)\s+(-?\d+)\s+(\d+)/).map{|a| a.map(&:to_i)}]}

даст вам:

[[4, 0,
  [[1, 347980000, -2540000, 0],
   [2, 347980000, -20320000, 0],
   [3, 482600000, -20320000, 0],
   [4, 482600000, -2540000, 0]]],
 [4, 1,
  [[1, 0, -2540000, 0],
   [2, 345440000, -2540000, 0],
   [3, 345440000, -20320000, 0],
   [4, 0, -20320000, 0]]],
 [8, 2,
  [[1, 0, 0, 0],
   [2, 0, 35560000, 0],
   [3, 53340000, 35560000, 0],
   [4, 53340000, 76200000, 0],
   [5, 449580000, 76200000, 0],
   [6, 449580000, 30226000, 0],
   [7, 482600000, 30226000, 0],
   [8, 482600000, 0, 0]]],
 [4, 3,
  [[1, 0, 38100000, 0],
   [2, 50800000, 38100000, 0],
   [3, 50800000, 76200000, 0],
   [4, 0, 76200000, 0]]],
[4, 4,
  [[1, 482600000, 76200000, 0],
   [2, 482854000, 31750000, 0],
   [3, 450850000, 31750000, 0],
   [4, 450850000, 76200000, 0]]]]
0 голосов
/ 29 мая 2011

Я не уверен, что даже хочу знать, какова цель сканирования этого файла с помощью регулярного выражения.

Но вы знаете, было бы легко разобрать, используя практически любую технику , отличную от регулярных выражений.

На самом деле, с небольшим изменением синтаксиса 1 это хороший файл YAML:

- outline: 4 0
  - corner: 1 347980000 -2540000 0
  - corner: 2 347980000 -20320000 0
  - corner: 3 482600000 -20320000 0
  - corner: 4 482600000 -2540000 0

- outline: 4 1
. . .
. . .

И вот, идеально организованная структура данных с одной строкой Ruby:

 > pp YAML::load_file 'corners.yaml'
[{"outline"=>
   [{"corner"=>"1 347980000 -2540000 0"},
    {"corner"=>"2 347980000 -20320000 0"},
    {"corner"=>"3 482600000 -20320000 0"},
    {"corner"=>"4 482600000 -2540000 0"}]},
 {"outline"=>
   [{"corner"=>"1 0 -2540000 0"},
    {"corner"=>"2 345440000 -2540000 0"},
    {"corner"=>"3 345440000 -20320000 0"},
    {"corner"=>"4 0 -20320000 0"}]},
 {"outline"=>
   [{"corner"=>"1 0 0 0"},
    {"corner"=>"2 0 35560000 0"},
    {"corner"=>"3 53340000 35560000 0"},
    {"corner"=>"4 53340000 76200000 0"},
    {"corner"=>"5 449580000 76200000 0"},
    {"corner"=>"6 449580000 30226000 0"},
    {"corner"=>"7 482600000 30226000 0"},
    {"corner"=>"8 482600000 0 0"}]},
 {"outline"=>
   [{"corner"=>"1 0 38100000 0"},
    {"corner"=>"2 50800000 38100000 0"},
    {"corner"=>"3 50800000 76200000 0"},
    {"corner"=>"4 0 76200000 0"}]},
 {"outline"=>
   [{"corner"=>"1 482600000 76200000 0"},
    {"corner"=>"2 482854000 31750000 0"},
    {"corner"=>"3 450850000 31750000 0"},
    {"corner"=>"4 450850000 76200000 0"}]}]

1.Теперь я действительно использовал регулярное выражение vim (1) для преобразования файла :%s/^ */&- /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...