sed - как (не) соответствовать несоответствующим скобкам

top главным образом используется в интерактивном режиме (попытайтесь читать страницу справочника или нажать "h" в то время как top работает), и ps разработан для неинтерактивного использования (сценарии, извлекая некоторую информацию с конвейерами оболочки и т.д.)

4
15.11.2013, 04:41
3 ответа

Лично, если бы мои регулярные выражения приближались к этому уровню сложности, то я просто переключил бы целую операцию на Perl. Эти соглашения с произвольным числом открытых фигурных скобок/круглых скобок/фигурных скобок:

$ perl -ne '@open=/[\[({]/g; @close=/[)\]}]/g; 
             if($#close == $#open){s/(.+?)\.is/($1).is/} print' file

Или, более компактный:

$ perl -pne 's/(.+?)\.is/($1).is/ if $#{/[\[({]/g} == $#{/[)\]}]/g}' file

Или больше завершенное, этот может иметь дело со случаями как [} (но все еще сбои на случаях как )():

  $ perl -pne '@osqb=/\[/g; @csqb=/\]/g; 
               @ocb=/\{/g; @ccb=/\}/g; 
               @op=/\(/g; @cp=/\)/g;
               if($#osqb == $#csqb && $#ocb==$#ccb && $#op == $#cp){
                    s/(.+?)\.is/($1).is/
               }' file

При выполнении на примере это распечатает

(this_thing).is 24
(that).is 50      
(a[23]).is == 10 
(a).is true      
(this_thing).is 24
this_thing.is (24
((that).is 50
(a[23].is == 10
a.is ( true
(this_thing.is 24
a{.is true
this_thing{.is 24
a[.is true
this_thing[.is 24 

Объяснение

  • perl -ne : обработайте входной файл линию за линией (-n) и запущенный скрипт, данный -e.
  • @open=/[\[({]/g; : найдите все вводные глифы и сохраните результат в названном массиве @open.
  • @close=/[)\]}]/g; : как выше, но для заключительных глифов.
  • if($#close == $#open) : если количество вводных глифов равно количеству заключительных глифов (если, другими словами, там подвешивают круглые скобки и т.д.)...
  • s/(.+?)\.is/($1).is/ :... затем замените самую короткую строку, которая заканчивается в .is с собой включил в круглых скобках.
  • Последнее print вне скобок и будет выполняться, была ли замена или нет.
5
27.01.2020, 20:51
  • 1
    Это хорошо, но имеет некоторые ошибки. пример [} будет соответствовать, так будет )( и т.д. –  ctrl-alt-delor 15.11.2013, 11:03
  • 2
    Гм, я не имею gksu установленный, таким образом, это вероятно, что перестало работать. Я действительно имею pkexec установленный..., когда я выполняю его, я добираюсь Error executing command as another user: No authentication agent was found. ---------121 верный--------133348----@richard, я предполагаю, что те ситуации не вероятны, но да, он перестанет работать на них. –  terdon♦ 15.11.2013, 15:18
  • 3
    @richard благодарит, я отредактировал свой ответ с более устойчивым примером. Все еще сбои на )( но фиксация, которая делала бы все это слишком долго. –  terdon♦ 15.11.2013, 16:15
  • 4
    +1 для, "если бы мои регулярные выражения приближались к этому уровню сложности, я просто переключил бы целую операцию на Perl" –  Joseph R. 17.11.2013, 01:07

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

Существует классификация грамматик, которые показывают это: регулярный, контекстно-свободный, и т.д. Парные скобки не могут быть сделаны с регулярным языком. Таким образом, Вы не можете сделать этого надежно.

1
27.01.2020, 20:51

Подробно останавливаясь на ответе terdon, можно использовать Perl, чтобы действительно проанализировать вложенные вводные конструкции. Вот regex, который должен сделать это:

$balanced_parens_grammar = qr/
  (?(DEFINE)                         # Define a grammar
    (?<BALANCED_PARENS> 
       \(                            # Opening paren
          (?:                        # Group without capturing
              (?&BALANCED_PARENS)    # Nested balanced parens
             |(?&BALANCED_BRACKETS)  # Nested balanced brackets
             |(?&BALANCED_CURLIES)   # Nested balanced curlies
             |[^)]*                  # Any non-closing paren
           )                         # End alternation
        \)                           # Closing paren
    )
    (?<BALANCED_BRACKETS> 
       \[                            # Opening bracket
          (?:                        # Group without capturing
              (?&BALANCED_PARENS)    # Nested balanced parens
             |(?&BALANCED_BRACKETS)  # Nested balanced brackets
             |(?&BALANCED_CURLIES)   # Nested balanced curlies
             |[^\]]*                 # Any non-closing bracket
           )                         # End alternation
        \]                           # Closing bracket
    )
    (?<BALANCED_CURLIES> 
       {                             # Opening curly
          (?:                        # Group without capturing
              (?&BALANCED_PARENS)    # Nested balanced parens
             |(?&BALANCED_BRACKETS)  # Nested balanced brackets
             |(?&BALANCED_CURLIES)   # Nested balanced curlies
             |[^}]*                  # Any non-closing curly
           )                         # End alternation
        }                            # Closing curly
    )
  )
  (?<BALANCED_ANY>
     (?:
         (?&BALANCED_PARENS)    
        |(?&BALANCED_BRACKETS)  
        |(?&BALANCED_CURLIES)   
     )
  )
/x;

Используйте его как так:

if( $line =~ m/
        ^
          [^()\[\]{}]*       # Any non-parenthetical punctuation
          (?&BALANCED_ANY)?  # Any balanced paren-types
          [^()\[\]{}]*
        $
        $balanced_parens_grammar/x){
    # Do your magic here
}

Отказ от ответственности

Код полностью не тестируется. Вероятно, содержит ошибки.

1
27.01.2020, 20:51
  • 1
    , Ничего себе, +1. Я действительно должен учиться как qr работы. –  terdon♦ 17.11.2013, 05:20
  • 2
    @terdon Спасибо. FWIW, тем не менее, qr// не имеет никакого отношения к определению грамматики: Вы, возможно, записали все это в m// оператор и это работали бы точно также. qr// предварительно компилирует regex, который, как ожидают, не изменится позже и так как это типично для грамматики, я использовал qr// здесь. Я думаю, что это делает вещи более читаемыми, также. –  Joseph R. 17.11.2013, 10:02
  • 3
    , хорошо, я знал qr скомпилированный regex, но никогда не использовали его. Определение грамматики, о котором я ничего не знаю так, я предположил, что эти два были соединены. Похож на мощный инструмент. –  terdon♦ 17.11.2013, 15:40
  • 4
    @terdon Я тоже. Я только недавно узнал об определении грамматики в Perl, таким образом, я не могу дождаться, чтобы экспериментировать :). Если Вы думаете, что это - мощная попытка, ищущая правила Perl 6! –  Joseph R. 17.11.2013, 20:47

Теги

Похожие вопросы