Извлечь 2 числа, которым предшествуют две разные строки из абзаца, используя регулярное выражение Tcl

Мне нужно извлечь два разных числа, которым предшествуют две разные строки. Employee Id--> Employee16(мне нужно 16) и Employee links--> Employee links:2 (мне нужно 2). Исходная строка выглядит следующим образом:

Employee16, Employee name is QueenRose
  Working for 46w0d
  Billing is Distributed
  65537 assigned tasks, 0 reordered, 0 unassigned
  0 discarded, 0 lost received, 5/255 load
  received sequence unavailable, 0xC2E7 sent sequence
  Employee links: 2 active, 0 inactive (max not set, min not set)
    Dt3/5/10:0, since 46w0d, no tasks pending
    Dt3/5/10:10, since 21w0d, no tasks rcvd
 Employee is currently working in Hardware section.

Employee19, Employee name is Edward11
  Working  for 48w4d
  Billing is Distributed
  206801498 assigned tasks, 0 reordered, 0 unassigned
  655372 discarded, 0 lost received, 9/255 load
  received sequence unavailable, 0x23CA sent sequence
  Employee links: 7 active, 0 inactive (max not set, min not set)
    Dt3/5/10:0, since 47w2d, tasks pending
    Dt3/5/10:10, since 28w6d, no tasks pending
    Dt3/5/10:11, since 18w4d, no tasks pending
    Dt3/5/10:12, since 18w4d, no tasks pending
    Dt3/5/10:13, since 18w4d, no tasks pending
    Dt3/5/10:14, since 18w4d, no tasks pending
    Dt3/5/10:15, since 7w2d, no tasks pending
   Employee is currently working in Hardware sectione.

Employee6 (inactive)
  Employee links: 2
    Dt3/5/10:0 (inactive)
    Dt3/5/10:10 (inactive)

Employee7 (inactive)
  Employee links: 2
    Dt3/5/10:0 (inactive)
    Dt3/5/10:10 (inactive)

Пробовал со следующим:

Employee(\d+)[^\n\r]*[^M]*Employee links:\s+(\d+)

Ожидается, что вывод будет выглядеть так:

16  2
19  7
 6  2
 7  2

Но не перечисляет все идентификаторы и ссылки. Может ли кто-нибудь помочь мне получить это?


tcl
person Madhu    schedule 07.05.2010    source источник


Ответы (2)


Проще всего извлечь данные из двух разных местоположений как два отдельных шага сопоставления. Кроме того, гораздо проще сначала разбить весь текст на абзацы.

Employee Id--> Employee16 (мне нужно 16)

Я бы извлек один такой:

regexp -line {^Employee(\d+),} $paragraph -> employeeNumber

(Для этой задачи вам нужен режим сопоставления строк, а не режим сопоставления по умолчанию «целая строка».)

Employee links--> Employee links:2 (мне нужно 2)

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

regexp -line {^\s+Employee links:\s*(\d+)(.*)$} $paragraph -> links rest

В этом случае я извлек не только $links, но и $rest строки, так как кажется, что вам, возможно, придется подумать о том, имеет ли это значение. Конечно, может оказаться, что следующее еще полезнее:

regexp -line {^\s+Employee links:\s*(\d+)(?:\s+active,\s+(\d+)\s+inactive)?} \
        $paragraph -> activeLinks inactiveLinks

В этом случае $inactiveLinks будет иметь пустую строку, если присутствовало только первое число (что, кажется, происходит, когда сотрудник неактивен; в этом случае вам нужно будет выполнить тривиальную логику, чтобы убрать).

Наконец, при использовании regexp не забудьте проверить результат на соответствие!
Надеюсь, это поможет.

person Donal Fellows    schedule 07.05.2010

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

foreach paragraph [regexp -all -inline {.*?\n{2,}} $text] {
    do something with $paragraph
}

В вашей попытке я вижу [^\n\r]* -- вы уверены, что у вас в тексте есть возврат каретки, а также символы новой строки?

person glenn jackman    schedule 07.05.2010