LINUX.ORG.RU

RegExp


0

0

Господа, помоготе распарсить данные
1. вырвать каждый параметр и его значение;
2. в значениях, где пропущен 0 (типа таких .39) его вставить.
нужны 2 этих выржения.
Каждая строка бдет парситься раздельо, естесственно.

+TNOM = 27        TOX = 4.5E-09    TSI = 5e-8       TBOX = 8E-08
+MOBMOD = 0       CAPMOD = 3       SHMOD = 0
+PARAMCHK=0       WINT = 0         LINT = -2E-08
+VTH0 = .52       K1 = .39         K2 = .1          K3 = 0
+KB1 = .95        K3B = 2.2        NLX = 7.2E-08
+DVT0 = .55       DVT1 = .28       DVT2 = -1.4
+DVT0W = 0        DVT1W = 0        DVT2W = 0
+NCH   = 3.3E+17  NSUB = 1E+15     NGATE = 1E+20
+DVBD0 = 60.0     DVBD1 = 1.1      VBSA = 0.0
+KB3 = 2.2        DELP = 0.02
+ABP = 0.9        MXC = 0.9        ADICE0 = 0.93
+KBJT1 = 1.0E-08  EDL = .0000005
+NDIODE = 1.13    NTUN = 14.0
+ISBJT = 2e-6     ISDIF = 1e-6      ISTUN = 0.0     ISREC = 1e-5
+XBJT = 0.01      XDIF = 0.01      XREC = 0.01      XTUN = 0.001
+U0 = 352         UA = 1.3E-11     UB = 1.7E-18     UC = -4E-10
+W0 = 1.16E-06    AGS = .25        A1 = 0           A2 = 1
+B0 = .01         B1 = 10
+RDSW = 700       PRWG = 0         PRWB = -.2       WR = 1
+RBODY = 0.0      RBSH = 0.0
+A0 = 1.4         KETA = -.67      VSAT = 135000
+DWG = 0          DWB = 0
+ALPHA0 = 0.0     ALPHA1 = 1.5     BETA0 = 20.5
+AII = 1.2        BII = 0.1e-7     CII = 0.8        DII = 0.6
+VOFF = -.14      NFACTOR = .7     CDSC = .00002    CDSCB    = 0
+CDSCD = 0        CIT = 0
+PCLM = 2.9       PVAG = 12        PDIBLC1 = .18    PDIBLC2 = .004
+PDIBLCB = -.234  DROUT = .2
+DELTA = .01      ETA0 = .01       ETAB = 0
*+DSUB = .3        RTH0_94    = .006
+DSUB = .3        RTH0    = .006
+CLC = .0000001   CLE = .6         CF = 1E-20       CKAPPA = .6
+CGDL = 1E-20     CGSL = 1E-20     KT1 = -.3        KT1L = 0

Заранее спасибо!



Последнее исправление: spike_by (всего исправлений: 1)
Ответ на: комментарий от sdio

хочу псле работы выражения получить массив парметров (TNOM, TOX, ..., CAPMOD,...) и массив их значений (27, 4.5E-09,..., 3,...)
предполагаю выраежие типа: [+|\s+|\n+|\t+](.*)s*=\s*(.*)[\s+|\n+|\t+] и наверно неправильное(. К томе же, это для одного набора (параметр=значение), а в строке их может быть много(.
Как их все из строки вырвать - не догоняю.

мне это в челе программы надо (Qt RegExp). Можно ли именно выражение?

spike_by
() автор топика
#!/usr/bin/php

<?php

    $content = file_get_contents ( "1.txt" );

    // ([A-Z0-9]+)\s*\=\s*([A-Z0-9\.\-]+)

    $pattern = "
    /
    ([^\s\*\+]+)\s*\=\s*([^\s]+)
    /xs";

    preg_match_all (
        $pattern, 
        $content, 
        $matches
        );  

    // var_dump ( $matches );

    // # Если нашел что-то.
    if ( count ( $matches [0] ) !== 0 )
        {

                    $matches_count = count ( $matches [0] );

                    for ($matches_pos = 0; $matches_pos < $matches_count; $matches_pos++)
                        {

                        $s = $matches [2][$matches_pos];

                        if ( substr ( $s, 0, 1 ) == "." )
                            {
                            $s = substr_replace ( $s, "0.", 0, 1 );
                            }
                        else
                            if ( substr ( $s, 0, 2 ) == "-." )
                                {
                                $s = substr_replace ( $s, "-0.", 0, 2 );
                                };

                        $matches [2][$matches_pos] = $s;

                        echo $matches [1][$matches_pos] . " = " . $matches [2][$matches_pos] . "\n";
                        
                       };


        };

?>
anonymous
()
#include <QFile>
#include <QVector>
#include <QPair>
#include <iostream>
#include <QRegExp>

typedef QPair<QString, double> valpair;
typedef QVector <valpair> Container;
Container parce_file(QFile & file)
{
    Container ret;
    QRegExp re("([A-Z][^ ]*) = ([^ ]*)");
    while (!file.atEnd()) {
        QString line = file.readLine();
        int pos = 0;
        while ((pos = re.indexIn(line, pos)) != -1)
        {
            ret.push_back(valpair(re.cap(1), re.cap(2).toDouble()));
            pos += re.matchedLength();
        }
    }
    return ret;
}

int main(int argc, char *argv[])
{
    /*if (argc!=2)
        return 1;
    QFile file(argv[1]);*/
    QFile file("/home/legolegs/test.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return 2;
    Container values = parce_file(file);
    for (Container::const_iterator i=values.begin();i!=values.end();++i)
        std::cout << i->first.toStdString() << "=" << i->second << std::endl;
    return 0;
}
legolegs ★★★★★
()
Ответ на: комментарий от Rastafarra

как-то так:

(use-package :simple-peg)

(defun extract-name (x)
  (format nil "~a~{~a~}" (first x) (second x)))
(defun extract-value (x)
  (read-from-string (format nil "~{~a~}" x)))
(defun extract-objects (xs)
  (let ((names #1=(make-array 0 :adjustable t :fill-pointer 0))
        (values #1#))
    (loop for (name value) in xs 
         do (vector-push-extend name names)
            (vector-push-extend value values))
    (cons names values)))

(defparser (*config* :start-symbol objects)
           (objects #'extract-objects) (* object)
           object (~ ws name eq value ws)
           (eq (constantly +ignore+)) (~ ws #\= ws)
           (ws (constantly +ignore+)) (* (/ #\return #\newline #\tab #\space))
           (value #'extract-value) (+ (/ digit #\. #\- #\E #\e #\+))
           (name #'extract-name) (~ garbage char (* (/ char digit)))
           (garbage (constantly +ignore+)) (~ (? #\*) (? #\+))
           char (/ #\_ (%-% #\A #\Z))
           digit (%-% #\0 #\9))

ну, с помощью http://love5an.livejournal.com/tag/peg

Love5an
()
Ответ на: комментарий от Love5an

Результаты sed 's/^ *//;s/ *$//'| grep -v '^$' | wc для каждого варианта (без коментов):

php 32 115 629

c++ 32 93 803

lisp 22 117 829

Хорошо видно, какой язык самый многословный и нечитаемый.

legolegs ★★★★★
()
while (<>) {
	chomp; s/^\+//;
	while (s/^\s*(\w+)\s*=\s*(\S+)//) {
		my ($k, $v) = ($1, $2);
		$map{$k} = ($v =~ s/^(-?)\./${1}0./, $v);
	}
}
print "$_ = $map{$_}\n" for keys %map;
gavv
()
Ответ на: комментарий от Rastafarra
* (with-open-file (in "test.txt") (funcall *config* in))
;;=>
#S(PARSE-RESULT
   :VALUE (#("TNOM" "TOX" "TSI" "TBOX" "MOBMOD" "CAPMOD" "SHMOD" "PARAMCHK"
             "WINT" "LINT" "VTH0" "K1" "K2" "K3" "KB1" "K3B" "NLX" "DVT0"
             "DVT1" "DVT2" "DVT0W" "DVT1W" "DVT2W" "NCH" "NSUB" "NGATE" "DVBD0"
             "DVBD1" "VBSA" "KB3" "DELP" "ABP" "MXC" "ADICE0" "KBJT1" "EDL"
             "NDIODE" "NTUN" "ISBJT" "ISDIF" "ISTUN" "ISREC" "XBJT" "XDIF"
             "XREC" "XTUN" "U0" "UA" "UB" "UC" "W0" "AGS" "A1" "A2" "B0" "B1"
             "RDSW" "PRWG" "PRWB" "WR" "RBODY" "RBSH" "A0" "KETA" "VSAT" "DWG"
             "DWB" "ALPHA0" "ALPHA1" "BETA0" "AII" "BII" "CII" "DII" "VOFF"
             "NFACTOR" "CDSC" "CDSCB" "CDSCD" "CIT" "PCLM" "PVAG" "PDIBLC1"
             "PDIBLC2" "PDIBLCB" "DROUT" "DELTA" "ETA0" "ETAB" "DSUB" "RTH0_94"
             "DSUB" "RTH0" "CLC" "CLE" "CF" "CKAPPA" "CGDL" "CGSL" "KT1"
             "KT1L")
           . #(27 4.5e-9 5.e-8 8.e-8 0 3 0 0 0 -2.e-8 0.52 0.39 0.1 0 0.95 2.2
               7.2e-8 0.55 0.28 -1.4 0 0 0 3.3e17 1.e15 1.e20 60.0 1.1 0.0 2.2
               0.02 0.9 0.9 0.93 1.e-8 5.e-7 1.13 14.0 2.e-6 1.e-6 0.0 1.e-5
               0.01 0.01 0.01 0.001 352 1.3e-11 1.7e-18 -4.e-10 1.16e-6 0.25 0
               1 0.01 10 700 0 -0.2 1 0.0 0.0 1.4 -0.67 135000 0 0 0.0 1.5 20.5
               1.2 1.e-8 0.8 0.6 -0.14 0.7 2.e-5 0 0 0 2.9 12 0.18 0.004 -0.234
               0.2 0.01 0.01 0 0.3 0.006 0.3 0.006 1.e-7 0.6 1.e-20 0.6 1.e-20
               1.e-20 -0.3 0))
   :STRING-VALUE "+TNOM = 27        TOX = 4.5E-09    TSI = 5e-8       TBOX = 8E-08 
+MOBMOD = 0       CAPMOD = 3       SHMOD = 0 
+PARAMCHK=0       WINT = 0         LINT = -2E-08 
+VTH0 = .52       K1 = .39         K2 = .1          K3 = 0 
+KB1 = .95        K3B = 2.2        NLX = 7.2E-08 
+DVT0 = .55       DVT1 = .28       DVT2 = -1.4 
+DVT0W = 0        DVT1W = 0        DVT2W = 0 
+NCH   = 3.3E+17  NSUB = 1E+15     NGATE = 1E+20 
+DVBD0 = 60.0     DVBD1 = 1.1      VBSA = 0.0 
+KB3 = 2.2        DELP = 0.02 
+ABP = 0.9        MXC = 0.9        ADICE0 = 0.93 
+KBJT1 = 1.0E-08  EDL = .0000005 
+NDIODE = 1.13    NTUN = 14.0 
+ISBJT = 2e-6     ISDIF = 1e-6      ISTUN = 0.0     ISREC = 1e-5 
+XBJT = 0.01      XDIF = 0.01      XREC = 0.01      XTUN = 0.001 
+U0 = 352         UA = 1.3E-11     UB = 1.7E-18     UC = -4E-10 
+W0 = 1.16E-06    AGS = .25        A1 = 0           A2 = 1 
+B0 = .01         B1 = 10 
+RDSW = 700       PRWG = 0         PRWB = -.2       WR = 1 
+RBODY = 0.0      RBSH = 0.0 
+A0 = 1.4         KETA = -.67      VSAT = 135000 
+DWG = 0          DWB = 0 
+ALPHA0 = 0.0     ALPHA1 = 1.5     BETA0 = 20.5 
+AII = 1.2        BII = 0.1e-7     CII = 0.8        DII = 0.6 
+VOFF = -.14      NFACTOR = .7     CDSC = .00002    CDSCB    = 0 
+CDSCD = 0        CIT = 0 
+PCLM = 2.9       PVAG = 12        PDIBLC1 = .18    PDIBLC2 = .004 
+PDIBLCB = -.234  DROUT = .2 
+DELTA = .01      ETA0 = .01       ETAB = 0 
*+DSUB = .3        RTH0_94    = .006 
+DSUB = .3        RTH0    = .006 
+CLC = .0000001   CLE = .6         CF = 1E-20       CKAPPA = .6 
+CGDL = 1E-20     CGSL = 1E-20     KT1 = -.3        KT1L = 0 
"
   :LENGTH 1640)
Love5an
()
Ответ на: комментарий от legolegs

строго говоря на qt тут только твое решение, стало быть пытаться что-то сравнивать смысла нет, ибо остальные решения элементарно не удовлетворяют требования.

однако ж.

Rastafarra ★★★★
()
Ответ на: комментарий от Rastafarra

>строго говоря на qt тут только твое решение, стало быть пытаться что-то сравнивать смысла нет

Это называется «русский тендер» :)

legolegs ★★★★★
()
Ответ на: комментарий от legolegs

legolegs> По условию надо в массив парсить
В исх. сообщении?

sdio ★★★★★
()
Ответ на: комментарий от legolegs

>Чтобы было по одному значению на строку и без мусора

Почему в самом sed-выражении не отгрэпать?

Led ★★★☆☆
()
Ответ на: комментарий от Led

Наверно потому, что возня с переводами строк получится. После каждого значеия надо начать новую строку, но после последнего в строке '\n' вставит сам сед. grep -o проще.

legolegs ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.