Perl字符串解析不同的变体

时间:2014-05-30 15:47:56

标签: regex perl parsing

专家......我正在继续my earlier query创建另一个问题....这个问题与之前的请求不同所以我认为更好地创建新线程而不是混淆专家的答案。

下面的代码将tnsfile中的每个别名连接到数据库...... 1.无论如何,我只能限制每个数据库连接一次,并且不允许不同的别名再次连接到同一个数据库吗?

我尝试使用哈希但无法修复此问题。

use strict;
use warnings;

if /^(([A-Za-z][A-Za-z0-9]*)(\.([A-Za-z][A-Za-z0-9]*))*)(\s|,|=)/
{
    {  
      $hashref->{$1}="";
    }
}

在regex下面可以从文件中选择每个SID值,但不能与if ...

结合使用
(/\(CONNECT_DATA\s+=\s+\(SID\s+=\s+(\w+\d+?)(\s+)?\)/)

示例文件(tnsfile.txt)

DB1.UK, DB2.UK =
  (
    (ADDRESS = (PROTOCAL = TCP))
    (CONNECT_DATA = (SID = db1))
  )

DB1.EU, DB2.CH =
  (
    (ADDRESS = (PROTOCAL = TCP))
    (CONNECT_DATA = (SID = db1))
  )

DB3.UK =
  (
    (ADDRESS = (PROTOCAL = TCP))
    (CONNECT_DATA = (SID = db3))
  )

DB3.US =
  (
    (ADDRESS = (PROTOCAL = TCP))
    (CONNECT_DATA = (SID = db3))
  )

DB4.UK.US, DB4.US =
  (
    (ADDRESS = (PROTOCAL = TCP))
    (CONNECT_DATA = (SID = db4))
  )

预期的$ hashref值:

DB1.UK  
DB3.UK  
DB4.UK.US

2 个答案:

答案 0 :(得分:0)

这远不是一个精炼的解决方案,如果你的tns文件的格式发生了巨大的变化,它会中断,但你可以尝试这样的事情:

use strict;

my (%tns, %sid, $tns);

open IN, 'tnsfile.txt' or die;
while (<IN>) {
  if (/^([\w.]+)/) {
    ($tns) = $1;
  }

  if (/SID *= *([\w.]+)/) {
    $tns{$tns} = $1 unless ($sid{$1}++)
  }
}
close IN;

print join "\n", keys %tns;

答案 1 :(得分:0)

您是否正在缓存数据库句柄?听起来像你。

如果是这样,您只需要创建一个将SID与数据库句柄相关联的新哈希。然后,只有在尚未加载SID的情况下,您才可以选择创建新句柄。

在伪代码中:

my %dbh_by_sid;

while (<DATA>) {
    my $sid = ...;

    my $dbh = $dbh_by_sid{$sid} ||= DBI->connect(...)
        or die "DB connect failed: $DBI::errstr";

    # ...
}

这样,如果已经连接了特定的SID,它将重用相同的句柄。