#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2011
    Posts
    2
    Rep Power
    0

    C# regex to repeat a header on every successive line


    This is my input text:
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916459-000-SAVSS, 75
    Terminal=916117-040-SAVSS, 75
    This is what I need to transform it into:
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916459-000-SAVSS, 75
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916117-040-SAVSS, 75
    The closest I have come is:
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916459-000-SAVSS, 75
    [Counter]
    Terminal=916117-040-SAVSS, 75
    This was using
    Find:
    (?<Header>(?<!(\]|DateTimeStamp.*)))(?<NL>\r\n)
    Replace:
    ${NL}[Counter]${NL}
    Any help in the right direction would be appreciated.
  2. #2
  3. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,965
    Rep Power
    9397
    Honestly I wouldn't use a regular expression for this. You'd need a loop anyways because the most you could do would be to match a Counter+DateTimeStamp+Terminal+Terminal and replace it with the Counter+DateTimeStamp duplicated between the two terminals: keep repeating that until it doesn't match anymore.

    Make a simple line-by-line reader. Like
    Code:
    new text = empty
    
    state = 1
    datetimestamp = empty
    for each line {
    	if state = 4 and line is Terminal {
    		new text += Counter + datetimestamp
    	} else if state = 3 and line is Terminal {
    		state = 4
    	} else if state = 2 and line is DateTimeStamp {
    		datetimestamp = line
    		state = 3
    	} else if state = 1 and line is Counter {
    		state = 2
    	} else {
    		state = 1
    	}
    	new text += line
    }
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2011
    Posts
    2
    Rep Power
    0
    Yup I know what u mean. These blocks are actually machine feedback files and I'm writing a parser.
    I wanted a modifiable architecture to transform the blocks into database fields and regex's in a config file seemed easy. Other option is to create classes at runtime using csharpcodeprovider and such.
    I don't want to recompile every time a change is needed.
    So the regex's are just me trying to avoid a full blown plugin setup.
  6. #4
  7. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,965
    Rep Power
    9397
    Going into a database? Hmm...

    So there's like three types of fields/lines:
    - A name, and appears like "[Name]"
    - A field with default values, these are preserved across lines
    - A field without default values, these must all be specified before anything happens

    If the input is
    Code:
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916459-000-SAVSS, 75
    Terminal=916117-040-SAVSS, 75
    DateTimeStamp=30/06/2011,01:00:25
    DateTimeStamp=30/06/2011,02:00:25
    Terminal=917249-010-SAVSS, 75
    then the steps are
    Code:
    "[Counter]"
    - a name. Table=Counter
    - the Counter table has
      - DateTimeStamp (has defaults)
      - Terminal (no defaults)
    
    "DateTimeStamp=30/06/2011,00:00:25"
    - DateTimeStamp has a value
    - still missing Terminal
    
    "Terminal=916459-000-SAVSS, 75"
    - have Terminal
    - all fields provided, do whatever you need to do with them
      - DateTimeStamp=30/06/2011,00:00:25
      - Terminal=916459-000-SAVSS, 75
    - reset all non-default fields
      - Have a DateTimeStamp from earlier
      - Terminal is missing
    
    "Terminal=916117-040-SAVSS, 75"
    - have Terminal
    - all fields provided, do whatever you need to do with them
      - DateTimeStamp=30/06/2011,00:00:25
      - Terminal=916117-040-SAVSS, 75
    - reset all non-default fields
      - Have a DateTimeStamp from earlier
      - Terminal is missing
    
    "DateTimeStamp=30/06/2011,01:00:25"
    - DateTimeStamp has a (new) value
    - still missing Terminal
    
    "DateTimeStamp=30/06/2011,02:00:25"
    - DateTimeStamp has a (new) value
    - still missing Terminal
    
    "Terminal=917249-010-SAVSS, 75"
    - have Terminal
    - all fields provided, do whatever you need to do with them
      - DateTimeStamp=30/06/2011,02:00:25
      - Terminal=917249-010-SAVSS, 75
    - reset all non-default fields
      - Have a DateTimeStamp from earlier
      - Terminal is missing
    Make sense?
  8. #5
  9. Turn left at the third duck
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2011
    Location
    Nelson, NZ
    Posts
    112
    Rep Power
    93
    Hey Bob,

    This may be too late for you, but I had a crack at your expression, and the following works. Might help someone on the same track.

    The Match expression:
    Code:
    (?s)\[Counter].*?(DateTimeStamp.*?)\r\n(Terminal.*?)\r\n(Terminal[^,]*?,\s*\d*)
    The Replace expression:
    Code:
    [Counter]\r\n\1\r\n\2\r\n[Counter]\r\n\1\r\n\3
    The Output:
    Code:
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916459-000-SAVSS, 75
    [Counter]
    DateTimeStamp=30/06/2011,00:00:25
    Terminal=916117-040-SAVSS, 75
    An ugly preg to make integrate it (your input is $subject):
    PHP Code:
    $result preg_replace('/(?s)\[Counter\].*?(DateTimeStamp.*?)\r\n(Terminal.*?)\r\n(Terminal[^,]*?,\s*\d*)/m''[Counter]\r\n\1\r\n\2\r\n[Counter]\r\n\1\r\n\3'$subject); 
    Is this what you wanted?

IMN logo majestic logo threadwatch logo seochat tools logo