Вопрос о регулярных выражениях Powershell, касающийся балансировки скобок - PullRequest
1 голос
/ 07 декабря 2009

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

Пример ввода:

CREATE Table Test ( РАЙОННЫЙ ВАРЧАР (3) УСТАНОВКА ХАРАКТЕРИСТИК ЛАТИНА НЕ БЕЗОПАСНА, CUSTOMER_ACCOUNT DECIMAL (8,0), CUSTOMER_SUB_ACCOUNT DECIMAL (3,0), SERVICE_SEQ_NUM DECIMAL (7,0), EFFECTIVE_DATE TIMESTAMP (0), SUBSCRIBER_SEQ_NUM DECIMAL (7,0) )

Спасибо!

Frederik

Ответы [ 2 ]

2 голосов
/ 07 декабря 2009

Традиционные регулярные выражения не способны проверять / соответствовать сбалансированным скобкам. Но несколько библиотек сделали расширения, которые допускают некоторую рекурсию. Например. pcre с его? R "квантификатором". И Microsoft добавила « балансировочные группы ». Вы можете найти пример этой функции для сопоставления (...) в http://oreilly.com/catalog/regex2/chapter/ch09.pdf

0 голосов
/ 07 декабря 2009

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

$str = @'
CREATE table test ( DISTRICT VARCHAR(3) CHARACTER SET LATIN NOT CASESPECIFIC,
  CUSTOMER_ACCOUNT DECIMAL(8,0), 
  CUSTOMER_SUB_ACCOUNT DECIMAL(3,0), 
  SERVICE_SEQ_NUM DECIMAL(7,0), 
  EFFECTIVE_DATE TIMESTAMP(0), 
  SUBSCRIBER_SEQ_NUM DECIMAL(7,0) )
'@

$str -split '(?<!\d),'
CREATE table test ( DISTRICT VARCHAR(3) CHARACTER SET LATIN NOT CASESPECIFIC
 CUSTOMER_ACCOUNT DECIMAL(8,0)
 CUSTOMER_SUB_ACCOUNT DECIMAL(3,0)
 SERVICE_SEQ_NUM DECIMAL(7,0)
 EFFECTIVE_DATE TIMESTAMP(0)
 SUBSCRIBER_SEQ_NUM DECIMAL(7,0) )

Обратите внимание, что для этого используется оператор -split PowerShell 2.0.

Для парного соответствия вы можете попробовать что-то вроде этого:

$re = [regex]@'
(?x)
\(
   (?>
       [^()]+
     |
       \( (?<DEPTH>)
     |
       \) (?<-DEPTH>)
   )*
   (?(DEPTH)(?!))
\)
'@

if ($str -match $re) {
    $matches[0]
}

Выходы:

( 
    DISTRICT VARCHAR(3) CHARACTER SET LATIN NOT CASESPECIFIC,  
    CUSTOMER_ACCOUNT DECIMAL(8,0),   
    CUSTOMER_SUB_ACCOUNT DECIMAL(3,0),   
    SERVICE_SEQ_NUM DECIMAL(7,0),   
    EFFECTIVE_DATE TIMESTAMP(0),   
    SUBSCRIBER_SEQ_NUM DECIMAL(7,0) 
)

См. Это сообщение в блоге для получения дополнительной информации о сопоставлении парен .

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