Python Script editor.replace Bug? concerning the characters '(' and ')'
-
Hi, I like padding around my brackets: (a)->( a )
therefore I am using a python script, that works in python, but it does something weird with ‘(’ and ‘)’ in Python Script in Notepad++ with editor.replace( ) , They both disappear, while it works for ‘[’, ‘{’, ‘}’, ‘]’
I am very confused. Please help me.
THIS IS THE SCRIPT I AM USING:
text=editor.getText()brackets_open=‘([{’
brackets_close=‘)]}’‘’’ adds padding to brackets, when there is none ‘’’
for index, character in enumerate( text ): #catch beginning and end issues
print( character )
if index==0: #first character in text
trailing_character=" "
if len( text )>1:
following_character=text[ index+1 ]
else:
following_character=" "
elif index==len( text )-1: #last character text
trailing_character=text[ index-1 ]
following_character=" "
else:
trailing_character=text[ index-1 ]
following_character=text[ index+1 ]if character in brackets_open and following_character!=' ': editor.replace( character, character+' ' ) elif character in brackets_close and trailing_character!=' ': editor.replace( character, ' '+character )
-
When wanting a literal
(
or)
in replacement text, it must be escaped, i.e.,\(
or\)
. -
Thank you so much. It works.
If anybody is interested, here is the full python script. It’s NOT python standard, but it really helps me read code.
text=editor.getText() ################################################################################ ''' compress operators, removes trailing and following space from operators ''' operators=[ '+', '-', '*', ':', '/' '//', '%', '**', ] assigners=[ '=', '+=', '-=', '*=', ':=', ] comparators=[ '==', '!=', '<', '>', '<=', '>=', ] for character in operators+assigners+comparators: if ' '+character+' ' in text: editor.replace( ' '+character+' ', character ) ################################################################################ ''' padd brackets, adds space to brackets right of open, left of close ''' brackets_open='([{' brackets_close=')]}' for index, character in enumerate( text ): ''' searching edge cases ''' if index==0: # first character trailing_character=" " if len( text )>1: following_character=text[ index+1 ] else: following_character=" " elif index==len( text )-1: # last character trailing_character=text[ index-1 ] following_character=" " else: trailing_character=text[ index-1 ] following_character=text[ index+1 ] ''' replacing ''' if character in brackets_open and following_character!=' ': if character=='(': editor.replace( character, '\('+' ' ) # '(' needs escape '\(' else: editor.replace( character, character+' ' ) elif character in brackets_close and trailing_character!=' ': if character=='\)': editor.replace( character, ' '+'\)' ) # '(' needs escape '\)' else: editor.replace( character, ' '+character ) ################################################################################
-
I was a little fast, operators work fine, but replace ‘(’ while working now, padds for every ‘(’. The original script hat functions that took the text, worked character by character and returned the final string, but doesn’t work with script. I have to find another way.
-
You could replace your entire script with a sequence of regex-replaces (documentation here), which could then be saved as a macro and bound to a keyboard shortcut.
Regex-replace 1 (remove space after and before operators):
- Open the find/replace form (
Edit->Replace...
from the Notepad++ main menu, or Ctrl+H with default keybindings) - Set the following options:
- Search mode set to
Regular expressions
- Wrap around checked.
- Find what:
\h*([+-*<>:=]=?|!=|//?|%|\*\*)\h*
- Replace with:
${1}
- Search mode set to
- Hit Replace all
Regex-replace 2 (add exactly one space before and after any of
{}[]()
)
The same as the previous steps, except in step 2,
Find what:(?<!\s)[(){}\[\]](?!\s)
Replace with:\x20${0}\x20
(note that\x20
is a way of rendering the literal space character so that it’s visible)I haven’t tested either of these regexes, but I’m pretty sure they should do what you want.
By the way, your script’s runtime will be proportional to the square of the length of the text (i.e., will be extremely slow if you run it on a long file), because it does a global operation (
editor.replace
) for every character in the text. Whenever you’re writing a script in any language, always ask yourself if there’s a way to do a series of local modifications rather than a global modification. And remember: strings are immutable, so you can’t perform local modifications to a string in Python. That’s a lot of the reason why regular expressions are so handy: they avoid having to do potentially very slow and clunky changes to strings. - Open the find/replace form (
-
Thank you :) I will try that.
But before, I solved my problem by creating a string, clear the editor and then add the string. It works. Don’t know if it’s fast. I am new to programming.
text=editor.getText() ################################################################################ ''' compress operators, removes trailing and following space from operatios ''' operators=[ '+', '-', '*', ':', '/' '//', '%', '**', ] assigners=[ '=', '+=', '-=', '*=', ':=', ] comparators=[ '==', '!=', '<', '>', '<=', '>=', ] for character in operators+assigners+comparators: if ' '+character+' ' in text: editor.replace( ' '+character+' ', character ) ################################################################################ ''' padd brackets, adds space to brackets right of open, left of close ''' brackets_open='([{' brackets_close=')]}' result='' for index, character in enumerate( text ): ''' searching edge cases ''' if index==0: # first character trailing_character=" " if len( text )>1: following_character=text[ index+1 ] else: following_character=" " elif index==len( text )-1: # last character trailing_character=text[ index-1 ] following_character=" " else: trailing_character=text[ index-1 ] following_character=text[ index+1 ] ''' replacing ''' if character in brackets_open and following_character!=' ': if character=='(': result+='\('+' ' #needs escape '\(' needs escape '\(' else: result+=character+' ' elif character in brackets_close and trailing_character!=' ': if character=='\)': result+=' '+'\(' #needs escape '\)' else: result+=' '+character else: result+=character ################################################################################ editor.clearAll( ) editor.addText( result ) ################################################################################
-
Are you sure your script is doing what you expect it to do?
Let me recap what you do
- you
retrieve
the current text content - you replace the operators_assigners_comparators in the
current
text - you iterate the
retrieved
text (retrieved text
!=current text
) to create a new content and replace thecurrent
text.
Furthermore, if you use the
replace
method, you do not need to escape the(
; this is only necessary if you userereplace
(note, rereplace, this is the regular expression replace form)Instead of deleting and adding text, you can use
setText
in one go.General advice:
There is no need to build strings like
result+='\('+' '
useresult+='\( '
use a script layout like
def main(): here your code main()
This gives you the option to return from a function, as the standard exit functions do what they should do, they end the process, in this case this would be notepad++.
Eg.def main(): if x == y: # oops something went wrong exit the script return main()
vs.
def main(): if x == y: # oops NOW NPP CRAHSES exit() main()
- you