Search Replace Action - RegEx Substitution and capture group

415 views
Skip to first unread message

francwalter

unread,
Aug 10, 2016, 4:31:20 PM8/10/16
to Tasker
Hallo

I don't see the exact function how the Search Replace action works.
I have problems with the subtitiution and the capture group.

Lets say I have a variable:
network={
    ssid
="EasyBox-123456"
    scan_ssid
=1
    psk
="ABCDEF01"
    key_mgmt
=WPA-PSK
}

network
={
    ssid
="FRITZ!Box 7330 SL"
    psk
="75467325462321364920"
    key_mgmt
=WPA-PSK
    priority
=9148
    disabled
=1
}

I want to have in an array named "presharedkey" only the psk values, e.g.
%presharedkey1=ABCDEF01
%presharedkey2=75467325462321364920

So I search for with the RegEx:
psk="([^"]+)"
and I Store Matches in:
%presharedkey
Replace Matches With:
$1

But the result is not what I expect. If I show %presharedkey1 I read:
psk="ABCDEF01"
and not only:
ABCDEF01

How can I get the capture group of the substitutions ($1,$2, etc.) into the result, with the Search Replace action?
Is this possible or do I need another action for this?

Thanks

frank

Robert Ryan

unread,
Aug 10, 2016, 4:52:49 PM8/10/16
to Tasker
Change your regex to (?<=psk=")[^"]+ and remove Replace Matches:


Test (36)

A1: Variable Set [
Name:%text
To:network={


ssid="EasyBox-123456"
scan_ssid=1
psk="ABCDEF01"
key_mgmt=WPA-PSK
}
network={
ssid="FRITZ!Box 7330 SL"
psk="75467325462321364920"
key_mgmt=WPA-PSK
priority=9148
disabled=1
}

Do Maths:Off
Append:Off ]

A2: Variable Search Replace [
Variable:%text
Search:(?<=psk=")[^"]+
Ignore Case:Off
Multi-Line:Off
One Match Only:Off
Store Matches In:%presharedkey
Replace Matches:Off
Replace With:$1 ]

A3: Flash [
Text:%presharedkey()
Long:Off ]

francwalter

unread,
Aug 11, 2016, 9:43:17 AM8/11/16
to Tasker
Am Mittwoch, 10. August 2016 22:52:49 UTC+2 schrieb Robert Ryan:
Change your regex to (?<=psk=")[^"]+ and remove Replace Matches:


        ....


that positive Lookbehind did the trick :) Thank you!
Now I have it all together, my little Task, which I use to read from my SGS4 with CM13 all wifi ssids with keys.
This is the description:

WlanKeys (609)
    A1
: [X] Popup [ Title:Info Text:Gets from the wifi file:
/data/misc/wifi/wpa_supplicant.conf
all ssids
(ssid) and keys (psk).
Compares in the for-loop each ssid from the list with the actual ssid if connected and shows a popup if found.
The actual psk will be copied to the clipboard.
If the acutal ssid is not in the list (e.g. not connected), the complete list (ssid;psk) of ssid and keys are copied to the clipboard. Background Image: Layout:Popup Timeout (Seconds):5 Show Over Keyguard:Off ]
    A2
: Flash [ Text:Please wait, while wifi keys are gathered... Long:On ]
    A3
: Variable Set [ Name:%wifipath To:/data/misc/wifi/wpa_supplicant.conf Do Maths:Off Append:Off ]
    A4
: Run Shell [ Command:su
cat
%wifipath Timeout (Seconds):5 Use Root:On Store Output In:%wlan Store Errors In:%error Store Result In: Continue Task After Error:On ]
    A5
: If [ %error Set ]
    A6
: Popup [ Title:Error Text:%error Background Image: Layout:PopupFullSmallFont Timeout (Seconds):30 Show Over Keyguard:On ]
    A7
: Stop [ With Error:Off Task: ]
    A8
: End If
    A9
: Variable Search Replace [ Variable:%wlan Search:network=\{[^}]+\} Ignore Case:Off Multi-Line:On One Match Only:Off Store Matches In:%wlannetwork Replace Matches:Off Replace With:$1 ]
    A10
: Test Net [ Type:Wifi SSID Data: Store Result In:%ssidconnected Continue Task After Error:On ]
    A11
: Variable Set [ Name:%ssidconnected To:0 Do Maths:Off Append:Off ] If [ %ssidconnected !Set ]
    A12
: For [ Variable:%count Items:1:%wlannetwork(#) ]
    A13
: Variable Search Replace [ Variable:%wlannetwork(%count) Search:(?<=psk=")[^"]+ Ignore Case:Off Multi-Line:On One Match Only:Off Store Matches In:%wlanpsk Replace Matches:Off Replace With:$1 ]
    A14
: Variable Search Replace [ Variable:%wlannetwork(%count) Search:(?<=ssid=")[^"]+ Ignore Case:Off Multi-Line:On One Match Only:Off Store Matches In:%wlanssid Replace Matches:Off Replace With:$1 ]
    A15
: Variable Set [ Name:%wlanssidpsk To:(%wlanssid();%wlanpsk())
 
Do Maths:Off Append:On ]
    A16
: If [ %ssidconnected eq %wlanssid() ]
    A17
: Popup [ Title:WLAN Login Text:ssid: %wlanssid()
psk
: %wlanpsk() copy to clipboard Background Image: Layout:Popup Timeout (Seconds):15 Show Over Keyguard:Off ]
    A18
: Set Clipboard [ Text:%wlanpsk() Add:Off ]
    A19
: Variable Set [ Name:%copyall To:no Do Maths:Off Append:Off ]
    A20
: End If
    A21
: End For
    A22
: Set Clipboard [ Text:%wlanssidpsk Add:Off ] If [ %copyall !Set ]

 It is working like this:
On my system and maybe on others too, all wifi connections are stored in a file wpa_supplicant.conf.
The path is to set if different.
If the task starts, Tasker looks if the actual connected wifi is in the list (must be though!) and shows its psk in a popup.
This is explained in the first action (commented out).

Works good :)

frank

Frank Röhm

unread,
Aug 11, 2016, 9:47:00 AM8/11/16
to tas...@googlegroups.com
... and here is the export as file (xml) for importing it into tasker.
WlanKeys.tsk.xml

francwalter

unread,
Aug 11, 2016, 9:56:49 AM8/11/16
to Tasker
... and here as text (xml) for import in Tasker:

<TaskerData sr="" dvi="1" tv="4.8u5">
   
<Task sr="task609">
       
<cdate>1470851385619</cdate>
       
<edate>1470922585527</edate>
       
<id>609</id>
       
<nme>WlanKeys</nme>
       
<pri>100</pri>
       
<Action sr="act0" ve="7">
           
<code>550</code>
           
<on>false</on>
           
<Str sr="arg0" ve="3">Info</Str>
           
<Str sr="arg1" ve="3">Gets from the wifi file:

/data/misc/wifi/wpa_supplicant.conf
all ssids (ssid) and keys (psk).
Compares in the for-loop each ssid from the list with the actual ssid if connected and shows a popup if found.
The actual psk will be copied to the clipboard.
If the acutal ssid is not in the list (e.g. not connected), the complete list (ssid;psk) of ssid and keys are copied to the clipboard.</Str>
           
<Str sr="arg2" ve="3"/>
           
<Str sr="arg3" ve="3">Popup</Str>
           
<Int sr="arg4" val="5"/>
           
<Int sr="arg5" val="0"/>
       
</Action>
       
<Action sr="act1" ve="7">
           
<code>548</code>
           
<Str sr="arg0" ve="3">Please wait, while wifi keys are gathered...</Str>
           
<Int sr="arg1" val="1"/>
       
</Action>
       
<Action sr="act10" ve="7">
           
<code>547</code>
           
<Str sr="arg0" ve="3">%ssidconnected</Str>
           
<Str sr="arg1" ve="3">0</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="0"/>
           
<ConditionList sr="if">
               
<Condition sr="c0" ve="3">
                   
<lhs>%ssidconnected</lhs>
                   
<op>13</op>
                   
<rhs></rhs>
               
</Condition>
           
</ConditionList>
       
</Action>
       
<Action sr="act11" ve="7">
           
<code>39</code>
           
<Str sr="arg0" ve="3">%count</Str>
           
<Str sr="arg1" ve="3">1:%wlannetwork(#)</Str>
       
</Action>
       
<Action sr="act12" ve="7">
           
<code>598</code>
           
<Str sr="arg0" ve="3">%wlannetwork(%count)</Str>
           
<Str sr="arg1" ve="3">(?&lt;=psk=")[^"]+</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="1"/>
           
<Int sr="arg4" val="0"/>
           
<Str sr="arg5" ve="3">%wlanpsk</Str>
           
<Int sr="arg6" val="0"/>
           
<Str sr="arg7" ve="3">$1</Str>
       
</Action>
       
<Action sr="act13" ve="7">
           
<code>598</code>
           
<Str sr="arg0" ve="3">%wlannetwork(%count)</Str>
           
<Str sr="arg1" ve="3">(?&lt;=ssid=")[^"]+</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="1"/>
           
<Int sr="arg4" val="0"/>
           
<Str sr="arg5" ve="3">%wlanssid</Str>
           
<Int sr="arg6" val="0"/>
           
<Str sr="arg7" ve="3">$1</Str>
       
</Action>
       
<Action sr="act14" ve="7">
           
<code>547</code>
           
<Str sr="arg0" ve="3">%wlanssidpsk</Str>
           
<Str sr="arg1" ve="3">(%wlanssid();%wlanpsk())
</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="1"/>
       
</Action>
       
<Action sr="act15" ve="7">
           
<code>37</code>
           
<ConditionList sr="if">
               
<Condition sr="c0" ve="3">
                   
<lhs>%ssidconnected</lhs>
                   
<op>0</op>
                   
<rhs>%wlanssid()</rhs>
               
</Condition>
           
</ConditionList>
       
</Action>
       
<Action sr="act16" ve="7">
           
<code>550</code>
           
<Str sr="arg0" ve="3">WLAN Login</Str>
           
<Str sr="arg1" ve="3">ssid: %wlanssid()
psk: %wlanpsk() copy to clipboard
</Str>
           
<Str sr="arg2" ve="3"/>
           
<Str sr="arg3" ve="3">Popup</Str>
           
<Int sr="arg4" val="15"/>
           
<Int sr="arg5" val="0"/>
       
</Action>
       
<Action sr="act17" ve="7">
           
<code>105</code>
           
<Str sr="arg0" ve="3">%wlanpsk()</Str>
           
<Int sr="arg1" val="0"/>
       
</Action>
       
<Action sr="act18" ve="7">
           
<code>547</code>
           
<Str sr="arg0" ve="3">%copyall</Str>
           
<Str sr="arg1" ve="3">no</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="0"/>
       
</Action>
       
<Action sr="act19" ve="7">
           
<code>38</code>
       
</Action>
       
<Action sr="act2" ve="7">
           
<code>547</code>
           
<Str sr="arg0" ve="3">%wifipath</Str>
           
<Str sr="arg1" ve="3">/data/misc/wifi/wpa_supplicant.conf</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="0"/>
       
</Action>
       
<Action sr="act20" ve="7">
           
<code>40</code>
       
</Action>
       
<Action sr="act21" ve="7">
           
<code>105</code>
           
<Str sr="arg0" ve="3">%wlanssidpsk</Str>
           
<Int sr="arg1" val="0"/>
           
<ConditionList sr="if">
               
<Condition sr="c0" ve="3">
                   
<lhs>%copyall</lhs>
                   
<op>13</op>
                   
<rhs></rhs>
               
</Condition>
           
</ConditionList>
       
</Action>
       
<Action sr="act3" ve="7">
           
<code>123</code>
           
<se>false</se>
           
<Str sr="arg0" ve="3">su
cat %wifipath
</Str>
           
<Int sr="arg1" val="5"/>
           
<Int sr="arg2" val="1"/>
           
<Str sr="arg3" ve="3">%wlan</Str>
           
<Str sr="arg4" ve="3">%error</Str>
           
<Str sr="arg5" ve="3"/>
       
</Action>
       
<Action sr="act4" ve="7">
           
<code>37</code>
           
<ConditionList sr="if">
               
<Condition sr="c0" ve="3">
                   
<lhs>%error</lhs>
                   
<op>12</op>
                   
<rhs></rhs>
               
</Condition>
           
</ConditionList>
       
</Action>
       
<Action sr="act5" ve="7">
           
<code>550</code>
           
<Str sr="arg0" ve="3">Error</Str>
           
<Str sr="arg1" ve="3">%error</Str>
           
<Str sr="arg2" ve="3"/>
           
<Str sr="arg3" ve="3">PopupFullSmallFont</Str>
           
<Int sr="arg4" val="30"/>
           
<Int sr="arg5" val="1"/>
       
</Action>
       
<Action sr="act6" ve="7">
           
<code>137</code>
           
<Int sr="arg0" val="0"/>
           
<Str sr="arg1" ve="3"/>
       
</Action>
       
<Action sr="act7" ve="7">
           
<code>38</code>
       
</Action>
       
<Action sr="act8" ve="7">
           
<code>598</code>
           
<Str sr="arg0" ve="3">%wlan</Str>
           
<Str sr="arg1" ve="3">network=\{[^}]+\}</Str>
           
<Int sr="arg2" val="0"/>
           
<Int sr="arg3" val="1"/>
           
<Int sr="arg4" val="0"/>
           
<Str sr="arg5" ve="3">%wlannetwork</Str>
           
<Int sr="arg6" val="0"/>
           
<Str sr="arg7" ve="3">$1</Str>
       
</Action>
       
<Action sr="act9" ve="7">
           
<code>341</code>
           
<se>false</se>
           
<Int sr="arg0" val="5"/>
           
<Str sr="arg1" ve="3"/>
           
<Str sr="arg2" ve="3">%ssidconnected</Str>
       
</Action>
       
<Img sr="icn" ve="2">
           
<nme>hd_device_access_accounts</nme>
       
</Img>
   
</Task>
</TaskerData>


By the way, the "Replace Matches" (CheckBox) with a backreference ($1, $2, ...) in "Replace With" is not replacing to the "Store Matches In" variable but directly to the "Variable" (input). This was a bit confusing for me first, but is now clear.



Dale Smith

unread,
Aug 11, 2016, 11:05:30 AM8/11/16
to Tasker


On Wednesday,I found it helpful to work through this one.  Hope I got it right. 

Example pattern to match: psk="ABCDEF01"

Regex statement:
(?<=psk=")[^"]+

(         group 
?<=    lookbehind psk="
)         in of group
[         POSIX group 
^        start of a string
"         literal quote 
]         end POSIX group 

francwalter

unread,
Jan 8, 2018, 7:09:20 AM1/8/18
to Tasker
Am Mittwoch, 10. August 2016 22:31:20 UTC+2 schrieb francwalter:
Hallo

I don't see the exact function how the Search Replace action works.
I have problems with the subtitiution and the capture group.

Some things about Taskers Search Replace, which I didn't find in the Userguide (of Search Replace):

- the Capturing token is not like in Android's Groups and capturing the backslash with number (e.g. \1, \2, etc.) as one could think (because of the link to that in the user guide at Matching Rules). In Tasker it is the $ (e.g. $1, $2, etc.)

- if "Replace Matches" is checked, the whole Variable (Input) is concerned and only the Matches are replaced.
E.g.
Variable Set
%input=This is a text with 123 numbers of many

Search Replace
Variable=%input
Search=(\d+) numbers of
Replace With:
$1

will set %input to: This is a text with 123

- "Store Matches In" results in an Tasker "array", so e.g. if I put there %matches I have to use %matches1, %matches2 etc. depending on how or which match I want to use. the %matches variable itself is empty.




Tasker Pro

unread,
Jan 8, 2018, 4:06:54 PM1/8/18
to Tasker
If you want to replace something in each entry of the %presharedkey() array, you'd just need to use a For Loop after the array has been created:


For: %num Items: 1:%presharedkey(#<)

Variable Search/Replace: %presharedkey(%num)
Search: <your search>
Replace Matches: On
Replace With: <your replacement>

End For

francwalter

unread,
Jan 14, 2018, 5:46:36 AM1/14/18
to Tasker
Am Montag, 8. Januar 2018 13:09:20 UTC+1 schrieb francwalter: 
...

- if "Replace Matches" is checked, the whole Variable (Input) is concerned and only the Matches are replaced.
E.g.
Variable Set
%input=This is a text with 123 numbers of many

Search Replace
Variable=%input
Search=(\d+) numbers of
Replace With:
$1

will set %input to: This is a text with 123 many


And to do a replacement of the whole text with only the capture group I use Positive Lookbehind:
E.g. I want to replace the following whole text with only the ammount of Mazda (which is 2900).
The text (Variable):

"Honda: 123
Mazda: 2900
Mitsubishi: 2
Volkswagen: 12
Mercedes Benz: 0"

So I would do in a Search Replace Action a Search For: "(?<=Mazda: )(\d+)"
Store Matches In: %mazda
Replace Matches: yes
Replace With: $1

And in %mazda1 I have my desired "2900"






Reply all
Reply to author
Forward
0 new messages