2009-12-07 5 views
1

Comment puis-je convertir une définition de colonne de table en un tableau de colonnes en utilisant regex sans tenir compte de la mise en forme? Je suis confus comment diviser sur "," car ils peuvent également apparaître dans la partie de définition de type de données (entre parenthèses correspondantes).Powershell regex question impliquant parenthèse d'équilibrage

entrée de l'échantillon:

create table test ( DISTRICT VARCHAR (3) jeu de caractères LATIN NON 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) )

Merci!

Frederik

Répondre

2

expressions Traditionnellement régulières ne sont pas en mesure de test pour/correspondant entre parenthèses équilibrées. Mais plusieurs bibliothèques ont fait des extensions qui permettent une certaine récursivité. Par exemple. pcre avec son "quantificateur" R. Et Microsoft a ajouté "balancing groups". Vous pouvez trouver un exemple de cette fonctionnalité pour faire correspondre (...) à http://oreilly.com/catalog/regex2/chapter/ch09.pdf

0

Je pense que vous pourriez utiliser un look négatif pour ce scénario puisque les virgules qui ne vous intéressent pas semblent précédées d'un nombre :

$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)) 

RemarqueCet utilise l'opérateur de PowerShell 2.0 -split.

Pour correspondance PAREN, vous pouvez essayer quelque chose comme ceci:

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

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

Sorties:

( 
    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) 
) 

Voir cette blog post for more help on paren matching.

+0

code ci-dessous fonctionne bien sur Powershell V1, donc je suis maintenant en mesure de diviser les colonnes correctement: $ txt = @ » DISTRICT VARCHAR (3) CARACTERES LATINE pas CASESPECIFIC, CUSTOMER_ACCOUNT DECIMAL (8,0), CUSTOMER_SUB_ACCOUNT DECIMAL (3,0) « @ [regex] :: de Split (txt $, '(<\ d),?!) Une question connexe est la suivante: Comment puis-je trouver la clôture correspondant parenthèse pour la parenthèse d'ouverture après le nom de la table afin que je puisse identifier la liste des colonnes qui est ensuite divisé avec l'expression rationnelle ci-dessus? – frederik