Why Does This Regex Not Work on This Block of Text?

Here is the regex I have tried to use to 'parse' out a block of text but it doesn't work.
I would like to break out the block of text into variables.

^Name:\s*(.?)\sEmail address:\s*(.?)\sPhone number:\s*(.?)\sZip code:\s*(.?)\sMessage:\s*([\s\S]?)\sInterested In:\s*(.?)\s$

I also tried:
^Name:\s*(.+)\s*

Email address: connie.rxxx@gmail.com
Phone number: 9171231234
Zip code: 12345
Message: Hi, we’re in need of xxx
Interested In: xxx, zzz

EDIT:
The email is a link actually
Name: Connie R
Email address: connie.rxxx@gmail.com
Phone number: 9171231234
Zip code: 12345
Message: Hi, we’re in need of xxx
Interested In: xxx, xxx

I got it:

^Name:\s*(.+)\r?\nEmail address:\s*(.+)\r?\nPhone number:\s*(.+)\r?\nZip code:\s*(.+)\r?\nMessage:\s*((?:.|\r?\n)*?)\r?\nInterested In:\s*(.+)\s*$

For a variant approach,

( converting the lines to a JSON record, and picking out named values with %JSONValue% )

see also:

1 Like

I have to say, your solution is a thing of beauty.
doesn't matter what is before the : which came into play....
Works like a charm,
thanx

2 Likes

Any kudos goes, I think, to all of @peternlewis 's work on %JSONValue% and custom delimiters for Variable Arrays.

The rest is just putting aside the familiar (but complicating, and very time-consuming) search and replace habit, and turning to splitting as a simpler and more powerful default.

3 Likes

If one of the values, say Message: is blank it errors.
Is there a way to alleviate that?

FYI I'm breaking out all of the values into separate variables that I then use via applescript in Filemaker Pro

ie.
Set Variable: Client_Message
%Variable%local_Value[5]\n%

Not sure that I have managed to reproduce that, or perhaps I'm not clear about the error that you're seeing.

Can you give me:

  1. A sample source text (with the kind of gap that you have in mind), and
  2. a description of the kind of error that it gives you ?

Can provisions be make in the code that, if there was no data entered for one of the 'fields' (in this case - message) that it would not error and just set that 'variable' to 'empty'?

Or should I simply put an if statement that if any of the 'variables' are empty, they get set to 'empty'?

I think I am not being very clear here....

Using the following block of text I get the included error in the log.

Name: Chris
Email: Chrisxxxx@yahoo.com
Phone: 1231231234
Zip Code: 12345
Message:
Interested In: House Cleaning Services

2024-08-24 12:31:39 Execute macro “Contact form regex 2024_08_19 ∑ K0315” from trigger Do Script

2024-08-24 12:31:39 Action 16119975 failed: Search Regular Expression failed to match ^([^ ]+) (.+)$

2024-08-24 12:31:39 Search Regular Expression failed to match ^([^ ]+) (.+)$ in macro “Contact form regex 2024_08_19 ∑ K0315” (while executing Search Variable “Client_Full_Name” Using Regular Expression (ignoring case)).

NOTE: Ignore the Client_Full_Name error, I have overcome that part of it.

Those messages appear to relate to a regular expression somewhere else ...

This macro on its own, for example, is quite happy with an empty Message value in the input:

%JSONValue% from colon-delimited lines (test of blank message).kmmacros (4.2 KB)


Are you using a regular expression at some subsequent stage of what you are doing ?

( possibly another opportunity to swap in something simpler – less fragile and time-consuming ? :slight_smile: )

ah, I'm using Filemaker Pro using applescript to get a KM variable, when that variable is empty I get an error from Filemaker Pro. So it must be KM via applescript not liking a blank variable?

--FMP Field from KM variable
tell application "Keyboard Maestro Engine"
  set Client_First_Name to value of variable "Client_First_Name"
  set Client_Last_Name to value of variable "Client_Last_Name"
  set Client_Email_Home to value of variable "Client_Email_Home"
  set Client_Phone to value of variable "Client_Phone"
  set Client_Zip_Code to value of variable "Client_Zip_Code"
  set Client_Message to value of variable "Client_Message"
end tell

--display dialog Client_Full_Name

tell application "FileMaker Pro"
	set cell "First Name" of current record to Client_First_Name
	set cell "Last Name" of current record to Client_Last_Name
	set cell "Email Home" of current record to Client_Email_Home
	set cell "Mobile Phone" of current record to Client_Phone
	set cell "Home Postal Code" of current record to Client_Zip_Code
	set cell "Directions" of current record to Client_Message
end tell

Screenshot 2024-08-24 at 12.54.38 PM

This is done after I have set a KM Variable to %Variable%local_Value[5]\n%

I'd have to see how you are binding values to the KM local_Value and Client_Message variables.

Even though your problem is solved, may I be permitted to show another solution? This works fine for me, but if your data can contain errors, you should add some error handling code. The simplest error handling would be just to set the flag to ignore errors on the Search action, which seems to work for me.

image

You could also "modify" the variable names by inserting the following statement in-between the two internal actions, like this:

image

1 Like

I wonder if your line-numbering is getting thrown out, in the case of blank lines,
by not having Include blank lines checked in the For Each action ?

( am I right in thinking that you have already tracked down the source of the regular expression error in your log ?)

1 Like

You can't get the value of a an empty variable. "Existence" is a bit vague in KM (it depends on where, and how, you look!), but the wiki tells us that:

Global Variables continue to exist (remained stored) until their value is set to the empty string

...and you're setting Client_Message to en empty string when there is nothing in your text block's line after "Client Message: ".

You get round this by using getvariable which handles empty/non-existing KM variables for you by returning an empty string:

tell application "Keyboard Maestro Engine"
  set Client_First_Name to getvariable "Client_First_Name"
  set Client_Last_Name to getvariable "Client_Last_Name"
  set Client_Email_Home to getvariable "Client_Email_Home"
  set Client_Phone to getvariable "Client_Phone"
  set Client_Zip_Code to getvariable "Client_Zip_Code"
  set Client_Message to getvariable "Client_Message"
end tell

Generally, always use getvariable rather than the older value of variable construct.

2 Likes

Yes thank you man....