如果没有匹配,正则表达式需要太长时间才能失败

时间:2012-06-19 02:08:18

标签: c# regex parsing

我有以下正则表达式字符串和下面的文本字符串。我有多个节点,我使用streamstreader读入一个字符串。之后我尝试使用regex.match()进行匹配以匹配字符串,当匹配时,即使存在大量节点,其运行速度也非常快。如果没有匹配项,regex.match()方法永远不会停止。

我的问题是,当字符串不匹配时,我只想捕捉异常。例如,在下面的数据节点中,我们说某些字段完全丢失,在这种情况下我可以捕获异常,问题是如果节点格式不同,如何停止匹配例程?

string pat = @"TEST_REPLICATE\s*{\s*REPLICATE_ID\s*([^}]*?)\s+ASSAY_NUMBER\s*([^}]*?)\s+ASSAY_VERSION\s*([^}]*?)\s+DILUTION_ID\s*([^}]*?)\s+SAMPLE_ID\s*([^}]*?)\s+SAMPLE_TYPE\s*([^}]*?)\s+TEST_ORDER_DATE\s*([^}]*?)\s+TEST_ORDER_TIME\s*([^}]*?)\s+TEST_INITIATION_DATE\s*([^}]*?)\s+TEST_INITIATION_TIME\s*([^}]*?)\s+TEST_COMPLETION_DATE\s*([^}]*?)\s+TEST_COMPLETION_TIME\s*([^}]*?)\s+ASSAY_CALIBRATION_DATE\s*([^}]*?)\s+ASSAY_CALIBRATION_TIME\s*([^}]*?)\s+TRACK\s*([^}]*?)\s+PROCESSING_LANE\s*([^}]*?)\s+MODULE_SN\s*([^}]*?)\s+LOAD_LIST_NAME\s*([^}]*?)\s+OPERATOR_ID\s*([^}]*?)\s+DARK_SUBREADS\s*([^}]*?)\s+SIGNAL_SUBREADS\s*([^}]*?)\s+DARK_COUNT\s*([^}]*?)\s+SIGNAL_COUNT\s*([^}]*?)\s+CORRECTED_COUNT\s*([^}]*?)\s+STD_BAK\s*([^}]*?)\s+AVG_BAK\s*([^}]*?)\s+STD_FOR\s*([^}]*?)\s+AVG_FOR\s*([^}]*?)\s+SHAPE\s*([^}]*?)\s+EXCEPTION_STRING\s*([^}]*?)\s+RESULT\s*([^}]*?)\s+REPORTED_RESULT\s*([^}]*?)\s+REPORTED_RESULT_UNITS\s*([^}]*?)\s+REAGENT_MASTER_LOT\s*([^}]*?)\s+REAGENT_SERIAL_NUMBER\s*([^}]*?)\s+RESULT_FLAGS\s*([^}]*?)\s+RESULT_INTERPRETATION\s*([^}]*?)\s+DILUTION_PROTOCOL\s*([^}]*?)\s+RESULT_COMMENT\s*([^}]*?)\s+DATA_MANAGEMENT_FIELD_1\s*([^}]*?)\s+DATA_MANAGEMENT_FIELD_2\s*([^}]*?)\s+DATA_MANAGEMENT_FIELD_3\s*([^}]*?)\s+DATA_MANAGEMENT_FIELD_4\s*([^}]*?)\s*}";  



    TEST_REPLICATE
    {
        REPLICATE_ID            353
        ASSAY_NUMBER            34224
        ASSAY_VERSION           99
        ASSAY_STATUS            VALKID
        DILUTION_ID         1
        SAMPLE_ID           "NC_3e2e2"
        SAMPLE_TYPE         Specimen
        TEST_ORDER_DATE         05.21.2012
        TEST_ORDER_TIME         03:44:01
        TEST_INITIATION_DATE        05.21.2012
        TEST_INITIATION_TIME        04:03:36
        TEST_COMPLETION_DATE        05.21.2012
        TEST_COMPLETION_TIME        04:29:32
        ASSAY_CALIBRATION_DATE      NA
        ASSAY_CALIBRATION_TIME      NA
        TRACK           1
        PROCESSING_LANE     1
        MODULE_SN       "EP334545004"
        LOAD_LIST_NAME          C:\BSQ_SASDACC\ASDADAjson
        OPERATOR_ID         "Q_SI"
        DARK_SUBREADS           NA
        SIGNAL_SUBREADS         NA
        DARK_COUNT          NA
        SIGNAL_COUNT            NA
        CORRECTED_COUNT         NA
        STD_BAK             NA
        AVG_BAK             NA
        STD_FOR             NA
        AVG_FOR             NA
        SHAPE               NA
        EXCEPTION_STRING        Test execution was stopped.
        RESULT              NA
        REPORTED_RESULT         NA
        REPORTED_RESULT_UNITS       NA
        REAGENT_MASTER_LOT      ASDADA
        REAGENT_SERIAL_NUMBER       25022
        RESULT_FLAGS            NA
        RESULT_INTERPRETATION       NA
        DILUTION_PROTOCOL       ASDASD
        RESULT_COMMENT          ASDA ASDA1
        DATA_MANAGEMENT_FIELD_1     NA
        DATA_MANAGEMENT_FIELD_2     NA
        DATA_MANAGEMENT_FIELD_3     NA
        DATA_MANAGEMENT_FIELD_4     NA
    }

2 个答案:

答案 0 :(得分:0)

  

您可以通过检查返回的Match对象的Success属性的值来确定是否在输入字符串中找到了正则表达式模式。如果匹配成功,则返回的Match对象的Value属性包含输入中与正则表达式模式匹配的子字符串。如果未找到匹配项,则其值为String.Empty。

来自http://msdn.microsoft.com/en-us/library/0z2heewz.aspx

当我使用您提供的值测试以下内容时,Success返回true。如果我将文本更改为不匹配的格式,则会按预期返回false。

var found = Regex.Match(inputString, pat).Success 

答案 1 :(得分:0)

三件事:

  1. 如果您编写这样的正则表达式,请使用选项RegexOptions.IgnorePatternWhitespace,它允许您使用正则表达式中的空格来使其更具可读性。这个空白不匹配!如果您想匹配某个空格,则必须将其转义\,或使用\s(您已经在做的事情)。

  2. 您的模式中不使用.,因此不需要RegexOptions.Singleline。此选项正在更改特殊字符.的行为,如果您不使用它,则不需要该选项。

  3. 如果您的模式失败,因为缺少某些关键字,您的正则表达式可能会使用[^}]*?进行匹配,我会将其缩小为使用\S*代替,{{1匹配一个非空白字符(适用于你的例子,我看到你想要提取的数据中没有空格),所以你的正则表达式应该更快地失败。

    更新:我的错误,你的例子在某些时候有空格。然后我会将\S替换为\S*。由于我没有使用Singleline选项,因此也不会与换行符匹配,因为我不成功,它不会在行的末尾包含空格。

    如果你可以选择缩小模式,那就更好了。例如。如果您知道某个值只能是数字,则只匹配.*?

  4. 尝试这种模式:

    \d+