Jump to content
Sign in to follow this  
Guy_

StringRegExpReplace stuff like ' 1) a) ' to ' (1) (a) ' + 'non-capturing' relevance?

Recommended Posts

Guy_

For my application, I have one string that may contain as item pointers a "space + single character/number + )"

For example:

Some text. 1) blah 2) blah a) yes b) no.

I'd like this to become:

Some text. (1) blah (2) blah (a) yes (b) no.

It seems I understand the use of the back reference $1, but I may not be grasping the functionality of non-capturing groups...

I hoped I could use the latter functionality so in the MAIN CODE I would not get the space between '(' and $1

The first code line below now giving me:

Some text. ( 1) blah ( 2) blah ( a) yes ( b) no.
Local $sOutput = StringRegExpReplace($sInput, '((?:\s).\))', ' ($1' )

As another trial, this doesn't seem to work either:

Local $sOutput = StringRegExpReplace($sInput, '(\s.\))', ' (' & StringRight('$1', 2) )

MAIN CODE:

Test()

Func Test()
    Local $sInput = 'Some text. 1) blah 2) blah a) yes b) no.'
; look for 'space + any char + )' and put '(' in front
    Local $sOutput = StringRegExpReplace($sInput, '( (?:\s).\) )' , ' ($1' )
    Display($sInput, $sOutput)
EndFunc   ;==>Test

Func Display($sInput, $sOutput)
    ; Format the output.
    Local $sMsg = StringFormat("Input:\t%s\n\nOutput:\t%s", $sInput, $sOutput)
    MsgBox(0, "Results", $sMsg)
EndFunc   ;==>Display

Thank you for any pointers :)

Edited by Guy_

Share this post


Link to post
Share on other sites
mikell

You only need to find the places just followed by "a char and ) " and put here a "("  

Local $sOutput = StringRegExpReplace($sInput, '(?=\w\))' , "(" )

As this matches a position this also works in such cases

Local $sInput = '0) Some text. 1) blah 2) blah a) yes b) no.'

:)

Edited by mikell

Share this post


Link to post
Share on other sites
Guy_

Clean! Thx :)

But...

I will also often have '(text)' or '(text).' in my string, and your code makes it '(tex(t)'

Since I'll probably almost always have a space in front and after the item text, my 'keep it simple ideal' is currently to search for

'space + any char + ) + space' and then put the '(' in.

If I just start by adding that space in your code, I already run into the old problem again of an output space in the wrong place...

Local $sOutput = StringRegExpReplace($sInput, '(?=\s\w\))' , "(" )

 

Therefore I was wondering if the solution could be related to the 'non-capturing groups' functionality,

allowing to search for the spaces, but not capturing / outputting them?

Share this post


Link to post
Share on other sites
mikell

Better refine the requirements for the searched position

Local $sOutput = StringRegExpReplace($sInput, '(?<=\s|^)(?=\w\))' , "(" )

Find the places just followed by "a char and ) " and preceded by "a space or start of string" (if needed)

Because if you do something like this

Local $sOutput = StringRegExpReplace($sInput, '(?:\s)(\w\))' , "($1" )

the non-capturing group is not captured but is still replaced, so the space is lost

So you'll have to grab all into backreferences

Local $sOutput = StringRegExpReplace($sInput, '(\s)(\w\))' , "$1($2" )

:)

Edited by mikell
  • Like 1

Share this post


Link to post
Share on other sites
Guy_

Wow :idiot:

I think I can actually understand that example too :sweating:

Thank you for the insight! :dance:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • luckyluke
      By luckyluke
      $t = '... 1-347-318-9643 1-347-318-9647 1-347-318-9648 1-347-318-9650 1-347-318-9651 1-347-318-9652 1-347-318-9653 1-347-318-9655 1-347-318-&nbsp;...' $pattern = '347.*?318.*?9655' $tmp = StringRegExpReplace($t, $pattern, "|||", 1) ConsoleWrite($tmp & @CRLF) However i got this output:
      ... 1-|||  1-347-318-&nbsp;...
      Why i got only that, where is the other string, i thought the output should be this:
      ... 1-347-318-9643  1-347-318-9647  1-347-318-9648  1-347-318-9650  1-347-318-9651  1-347-318-9652  1-347-318-9653  1-|||  1-347-318-&nbsp;...
    • ViciousXUSMC
      By ViciousXUSMC
      So I ran into this crazy "program" that cant be uninstalled via WMI, MSIExec, etc.
      The only way to uninstall it was from Add/Remove programs manually... Or I found if you find it in the registry under HKCU and run the  uninstall string, it will also uninstall.
      However the string in the registry cant be run directly in a cmd window because of the format errors.
      It has spaces without quotations, it has invalid characters, etc, etc 
      I know things run different when executed in the registry, so maybe there is a way I can run the regsitry key just like how the system does?  If so chime in.
      Otherwise I did this a crude way using several stringregexpreplace() functions and have it working.
      The solution feels so barbaric and crude that I wanted to post it so some of you guys better than me can clean up the code, maybe offer alternative ways to do it, or reduce the number of times I process the string.
      Here is the string right out of the registry:
      c:\Program Files\Common Files\Microsoft Shared\VSTO\10.0\VSTOInstaller.exe /Uninstall file:///C:/Users/it022565/AppData/Local/Temp/OOBAXTOWordAddIn/ApplicationXtender.AXTO.Word.vsto Here is my cave man scripting to turn this into a run able string.
       
      Func _UninstallOld() For $i = 1 to 100 ;Enumerate Registry $sEnumBase = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" ;Look in HKCU for the uninstall string for the old version $sEnum = RegEnumKey($sEnumBase, $i) If @Error Then Return If $iDebug = 1 Then MsgBox(0, "", $sEnum) If StringInStr(RegRead($sEnumBase & $sEnum, "DisplayName"), "Word Addin") Then ExitLoop Next If $iDebug = 1 Then MsgBox(0, "", $sEnum) $sKey = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & $sEnum $sKey2 = RegRead($sKey, "UninstallString") If $iDebug = 1 Then MsgBox(0, "Original Install Location", $sKey2) $sKey3 = StringRegExpReplace($sKey2, "(?i)(c:.*exe)", '"$1"') If $iDebug = 1 Then MsgBox(0, "", $sKey3) $sKey4 = StringRegExpReplace($sKey3, "(?i)file:///", "") If $iDebug = 1 Then MsgBox(0, "", $sKey4) $sKey5 = StringRegExpReplace($sKey4, "%20", " ") If $iDebug = 1 Then MsgBox(0, "", $sKey5) $sKey6 = StringRegExpReplace($sKey5, '(?i)((?<!")c:.*vsto)', '"$1"') If $iDebug = 1 Then MsgBox(0, "", $sKey6) RunWait(@ComSpec & ' /c ' & '"' & $sKey6 & ' /s"', "", @SW_HIDE) EndFunc Basically step by step I add quotations, strip bad characters, etc.  Kind of proud for using look behind for once
      Looking forward to what you guys come up with.
    • VIP
      By VIP
      Need help to make function better  with full infomation
      #include <Array.au3> #include <File.au3> _TEST(@ScriptFullPath) _TEST("A:") _TEST("A:\B.c") _TEST("D:\E\F\") _TEST("G:\H/../J.k/") _TEST("M:\N\k..J.k") _TEST("D:\E\F\..\G\G\I..J.K.M") Func _TEST($sFilePath) Local $sDrive = "", $sFullPathDir = "", $sDirPath = "", $sDirName = "", $sFileName = "", $sFileNameExt = "", $sExtension = "", $sExt = "" Local $aPathSplit = _PathSplitByRef($sFilePath, $sDrive, $sFullPathDir, $sDirPath, $sDirName, $sFileName, $sFileNameExt, $sExtension, $sExt) ConsoleWrite("!Path IN : " & $sFilePath & @CRLF) ; C:\Windows\System32\etc\hosts.exe ConsoleWrite("- Driver : " & $sDrive & @CRLF) ; C: ConsoleWrite("- DirPath : " & $sFullPathDir & @CRLF) ; C:\Windows\System32\etc\etc ConsoleWrite("- DirPath : " & $sDirPath & @CRLF) ; \Windows\System32\etc\ ConsoleWrite("- DirName : " & $sDirName & @CRLF) ; etc ConsoleWrite("- FileName : " & $sFileName & @CRLF) ; hosts ConsoleWrite("- FileNameExt: " & $sFileNameExt & @CRLF) ; hosts.exe ConsoleWrite("- Extension : " & $sExtension & @CRLF) ; .exe ConsoleWrite("- Ext : " & $sExt & @CRLF & @CRLF) ; exe ;~ ConsoleWrite("!Path IN : " & $aPathSplit[0] & @CRLF) ; C:\Windows\System32\etc\hosts.exe ;~ ConsoleWrite("- Driver : " & $aPathSplit[1] & @CRLF) ; C: ;~ ConsoleWrite("- DirPath : " & $aPathSplit[2] & @CRLF) ; C:\Windows\System32\etc\etc ;~ ConsoleWrite("- DirPath : " & $aPathSplit[3] & @CRLF) ; \Windows\System32\etc\ ;~ ConsoleWrite("- DirName : " & $aPathSplit[4] & @CRLF) ; etc ;~ ConsoleWrite("- FileName : " & $aPathSplit[5] & @CRLF) ; hosts ;~ ConsoleWrite("- FileNameExt: " & $aPathSplit[6] & @CRLF) ; hosts.exe ;~ ConsoleWrite("- Extension : " & $aPathSplit[7] & @CRLF) ; .exe ;~ ConsoleWrite("- Ext : " & $aPathSplit[8] & @CRLF) ; exe ;~ _ArrayDisplay($aPathSplit, "_PathSplit of " & $sFilePath) EndFunc ;==>_TEST Func _PathSplitByRef($sFilePath, ByRef $sDrive, ByRef $sFullPathDir, ByRef $sDirPath, ByRef $sDirName, ByRef $sFileName, ByRef $sFileNameExt, ByRef $sExtension, ByRef $sExt) If StringInStr($sFilePath,"..") Then $sFilePath=_PathFull($sFilePath) Local $aPartOfPath=StringRegExp($sFilePath, "^\h*((?:\\\\\?\\)*(\\\\[^\?\/\\]+|[A-Za-z]:)?(.*[\/\\]\h*)?((?:[^\.\/\\]|(?(?=\.[^\/\\]*\.)\.))*)?([^\/\\]*))$", $STR_REGEXPARRAYMATCH) ;~ If @error Then ReDim $aPartOfPath[9] ;~ $aPartOfPath[0] = $sFilePath ;~ EndIf $aPartOfPath[0] = $sFilePath ; C:\Windows\System32\etc\hosts.exe $sDrive = $aPartOfPath[1] ; C: $sFullPathDir = $aPartOfPath[1] & $aPartOfPath[2] ; C:\Windows\System32\etc If StringLeft($aPartOfPath[2], 1) == "/" Then $sDirPath = StringRegExpReplace($aPartOfPath[2], "\h*[\/\\]+\h*", "\/") Else $sDirPath = StringRegExpReplace($aPartOfPath[2], "\h*[\/\\]+\h*", "\\") EndIf $aPartOfPath[2] = $sFullPathDir ; C:\Windows\System32\etc $sDirName=StringReplace($sDirPath,"\","") $sDirName=StringReplace($sDirPath,"/","") $sFileName = $aPartOfPath[3] ; hosts $aPartOfPath[5] = $sFileName ; hosts $sExtension = $aPartOfPath[4] ; .exe $aPartOfPath[7] = $sExtension ; .exe $aPartOfPath[3] = $sDirPath ; \Windows\System32\etc\ $aPartOfPath[4] = $sDirName ; etc $aPartOfPath[6] = $sFileName & $sExtension ; hosts.exe $sFileNameExt = $aPartOfPath[6] ; hosts.exe $sExt = StringReplace($sExtension,".","") ; exe $aPartOfPath[8] = $sExt ; exe Return $aPartOfPath EndFunc ;==>_PathSplitByRef  
    • hawkair
      By hawkair
      Hi
      I am trying to insert line numbers in to a string
      with this script
      Func _MyInc () Static Local $i = 0 $i += 1 Return $i EndFunc Exit _InsertLines() Func _InsertLines()     $String = "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" $NewString =  Execute("'" & StringRegExpReplace($String,"[\r\n]*",  "' & _MyInc () & '\1" ) & "'") MsgBox (0, "", $NewString) EndFunc but I get this:
      1A23B45C67D8
      I never really could master how Execute works here and I always get some working example and make substitutions.
      But this is the closest i could get...
       
    • AutoBert
      By AutoBert
      The idea to use translation api:

      i used the script from @mikell to build this func:
      Func _Translate($sFrom, $from, $to) ;thanks to mikell (autoitscript.com) ;https://www.autoitscript.com/forum/topic/182893-prompt-me-how-to-see-the-text-in-the-translation-boxhttpstranslategooglecom/?do=findComment&comment=1313423 Local $url = "https://translate.googleapis.com/translate_a/single?client=gtx" $url &= "&sl=" & $from & "&tl=" & $to & "&dt=t&q=" & $sFrom Local $oHTTP = ObjCreate("Microsoft.XMLHTTP") $oHTTP.Open("POST", $url, False) $oHTTP.Send() Local $sData = $oHTTP.ResponseText $sData = StringRegExpReplace($sData, '.*?\["(.*?)"[^\[]*', "$1" & @CRLF) Return $sData EndFunc ;==>_Translate when i call this func with:
      $sText='AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting. It uses a combination of simulated keystrokes, mouse movement and window/control manipulation in order to automate tasks in a way not possible or reliable with other languages (e.g. VBScript and SendKeys). AutoIt is also very small, self-contained and will run on all versions of Windows out-of-the-box with no annoying "runtimes" required!' MsgBox(64,'',_Translate($sText,'en','de')) nearly all is seeing here:

      only the "!" is wrong "\" but when using 'auto' instead of 'en' the result is:

      2 lines are appended. So my question is, is it possible to extend the pattern (i never worked with regex) and in best case setting @extended with the detected language?
      @Trong: as you can see yet i am returning translated text and don't use GuiCtrlSetData to assign it to a EditBox.
×