How to match a string after a character when the line begins with one of two values?

StackOverflow https://stackoverflow.com/questions/22691715

  •  22-06-2023
  •  | 
  •  

Question

I have a text file that's in the following format:

# Email File
# List of email addresses
##############################
PRIMARY_EMAIL=abc@123.com
ALTERNATE_EMAIL=123@abc.com
#PRIMARY_EMAIL=def@456.com
#ALTERNATE_EMAIL=456@def.com
PRIMARY_EMAIL=ghi@789.com
ALTERNATE_EMAIL=789@ghi.com

This file contains the primary and alternate email addresses for employees. I'm using the file as input for a script I'm using to send a notification to the employees. Some of the email addresses are commented out if the employee is on leave and need to not be included in the results.

The problem I'm having is that I'm unable to match the email address after the "=" sign when the string begins with "PRIMARY_EMAIL" or "ALTERNATE_EMAIL".

Using the following code, I can obtain "PRIMARY_EMAIL", but it doesn't pick up "ALTERNATE_EMAIL". The code below works if I grab the input with two variables and specifically indicate "PRIMARY_EMAIL" or "ALTERNATE_EMAIL" in the regular expression, but I'd like to get everything at once in a single line of code if it's possible.

while (<$in_file>) {
    $line = $1 if (/^PRIMARY_EMAIL=(.*)|^ALTERNATE_EMAIL=(.*)/);
    chomp;
    if (defined $line) {
        push (@recipient, $line);
    }
}

$to = join("\n", @recipient);
print "\$to = \n", $to, "\n";

Output:

$to =
abc@123.com
ghi@789.com

As you can see, the output/regular expression is not including the values after "ALTERNATE_EMAIL".

The output should be:

$to = 
abc@123.com
123@abc.com
ghi@789.com
789@ghi.com

I've searched all over for a way to use alternation to match two different strings at the beginning of a line while only returning the potion after the "=" sign, but every example/explanation I've found only deals with a single match at the beginning of a string.

Thanks for the help.

Was it helpful?

Solution

Try this one:

my @recipient  = (join("", <DATA>) =~ /^(?:PRIMARY_EMAIL|ALTERNATE_EMAIL)=(.*)/mg);
my $to = join("\n", @recipient);
print "\$to = \n", $to, "\n";

__DATA__
# Email File
# List of email addresses
##############################
PRIMARY_EMAIL=abc@123.com
ALTERNATE_EMAIL=123@abc.com
#PRIMARY_EMAIL=def@456.com
#ALTERNATE_EMAIL=456@def.com
PRIMARY_EMAIL=ghi@789.com
ALTERNATE_EMAIL=789@ghi.com

join("", <DATA>) this is reading all the lines and joining into one. Then using regex I am parsing the emails into the array directly.

OTHER TIPS

Use branch reset /^(?|PRIMARY_EMAIL=(.*)|ALTERNATE_EMAIL=(.*))/

      ^
      (?|
           PRIMARY_EMAIL=
 br 1      ( .* )                        # (1)
        |  ALTERNATE_EMAIL=
 br 1      ( .* )                        # (1)
      )

Or, just this /^(?:PRIMARY_EMAIL|ALTERNATE_EMAIL)=(.*)/

 ^ 
 (?: PRIMARY_EMAIL | ALTERNATE_EMAIL )
 =
 ( .* )                             # (1)

test case

 while (<DATA>) {
     if (/^(?:PRIMARY_EMAIL|ALTERNATE_EMAIL)=(.*)/)
     {
        push (@recipient, $1);
     }
 }

 $to = join("\n", @recipient);
 print "\$to = \n", $to, "\n";

__DATA__
# Email File
# List of email addresses
##############################
PRIMARY_EMAIL=abc@123.com
ALTERNATE_EMAIL=123@abc.com
#PRIMARY_EMAIL=def@456.com
#ALTERNATE_EMAIL=456@def.com
PRIMARY_EMAIL=ghi@789.com
ALTERNATE_EMAIL=789@ghi.com

Output >>

 $to =
 abc@123.com
 123@abc.com
 ghi@789.com
 789@ghi.com

Here is another way

$/ = undef;
print join("\n",(<DATA> =~ /^(?:PRIMARY_EMAIL|ALTERNATE_EMAIL)=(.*)/mg));

__DATA__
# Email File
# List of email addresses
##############################
PRIMARY_EMAIL=abc@123.com
ALTERNATE_EMAIL=123@abc.com
#PRIMARY_EMAIL=def@456.com
#ALTERNATE_EMAIL=456@def.com
PRIMARY_EMAIL=ghi@789.com
ALTERNATE_EMAIL=789@ghi.com

Output >>

abc@123.com
123@abc.com
ghi@789.com
789@ghi.com
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top