import re
new_s1 = re.sub(r'[\W_]+','_',s1)
new_s2 = re.sub(r'[\W_]+','_',s2)
Input:
s1 = 'Hi th@re gu^ys!@#()tes t;"[]ing'
s2 = 'Hi th@re gu^ys!@#()tes t___;"[]ing'
Output:
>>> print(new_s1)
>>> Hi_th_re_gu_ys_tes_t_ing
>>> print(new_s2)
>>> Hi_th_re_gu_ys_tes_t_ing
Answer from user19168512 on Stack Overflowimport re
new_s1 = re.sub(r'[\W_]+','_',s1)
new_s2 = re.sub(r'[\W_]+','_',s2)
Input:
s1 = 'Hi th@re gu^ys!@#()tes t;"[]ing'
s2 = 'Hi th@re gu^ys!@#()tes t___;"[]ing'
Output:
>>> print(new_s1)
>>> Hi_th_re_gu_ys_tes_t_ing
>>> print(new_s2)
>>> Hi_th_re_gu_ys_tes_t_ing
import re
s = 'Hi th@re gu^ys!@#()tes t;"[]ing'
new_s = re.sub(r'[\W]+','_',s)
print(new_s)
One way is to use re.sub, that's my preferred way.
import re
my_str = "hey th~!ere"
my_new_string = re.sub('[^a-zA-Z0-9 \n\.]', '', my_str)
print my_new_string
Output:
hey there
Another way is to use re.escape:
import string
import re
my_str = "hey th~!ere"
chars = re.escape(string.punctuation)
print re.sub('['+chars+']', '',my_str)
Output:
hey there
Just a small tip about parameters style in python by PEP-8 parameters should be remove_special_chars and not removeSpecialChars
Also if you want to keep the spaces just change [^a-zA-Z0-9 \n\.] to [^a-zA-Z0-9\n\.]
str.replace is the wrong function for what you want to do (apart from it being used incorrectly). You want to replace any character of a set with a space, not the whole set with a single space (the latter is what replace does). You can use translate like this:
removeSpecialChars = z.translate ({ord(c): " " for c in "!@#$%^&*()[]{};:,./<>?\|`~-=_+"})
This creates a mapping which maps every character in your list of special characters to a space, then calls translate() on the string, replacing every single character in the set of special characters with a space.
python - How to replace special characters in file name with Underscore symbol using Unix? - Stack Overflow
python - Regex, replace all underscore and special char with spaces? - Stack Overflow
How to replace underscores with letters?
Replace special chars with underscores for environment variables with credentials
The problem in your code is that str.replace doesn't modify a string in place, but returns a copy with the replacement done. You have to assign it back if you want to replace the original string
word = word.replace(word[i], '_')
Make sure you understand the pieces you are working with, if you start with a simple program you can see that replace doesn't perform as you expect
w = 'abc'
w.replace('a', 'x') # should be w = w.replace(...)
print(w) # prints 'abc'
If I take the title of your question literally, you want to replace the letters with underscores only. That would leave all of the special characters and numbers intact. In that case you can use string.ascii_lettrs and join
def convert_letter(word):
''.join('_' if c in string.ascii_letters else c for c in word)
As you seem to have stated in other comments, you actually want the underscores to have a space between them, if that is the case then use ' '.join instead
Try
new_word = word.replace(word[i], '_ ')
From the documentations of string.replace(): It returns a copy of string s with all occurrences of substring old replaced by new.
word = "my example"
def convert_letter(word):
new_word = word
for i in range(0, len(word)):
if ord(word[i]) != 32:
new_word = new_word.replace(word[i], '_ ')
print(new_word)
convert_letter(word)
Underscore is considered a "word character" in PCRE regular expressions. If what you want to match is "anything that is not a word character or an underscore", try this:
new_str = re.sub(r'[\W_]', ' ', new_str)
The underscore is part of the \w character group. Use this instead:
new_str = re.sub(r'[^a-zA-Z0-9]', ' ', new_str)
which is the same as \w but minus the underscore.
I'm using Fibery to manage a bunch of business processes and trying to build a formula that uses their ReplaceRegex function, but struggling to achieve what I want.
ChatGTP keeps giving me solutions that don’t seem to work in Fibery’s approved RegEx format. I'm not entirely sure what they accept but they do link to this page in their documentation: https://medium.com/tech-tajawal/regular-expressions-the-last-guide-6800283ac034
If the input was:
Hello. I'm "___BOB___"! I'm feeling happy / healthy
I want the output to be:
hello_im_bob_im_feeling_happy_healthy
So basically:
-
All spaces should be replaced with underscores
-
All special characters (except for underscores) should be removed
-
There should never be more than 1 underscore in a row in the final output
I’ve got it mostly working with the following
Lower( ReplaceRegex( ReplaceRegex( "Hello. I'm "___BOB___"! I'm feeling happy / healthy", "[\s_]+", "_"), "[^a-zA-Z0-9_]", "") )
but it still spits out the following (based on my example):
hello_im__bob__im_feeling_happy__healthy
As you can see there’s a few spots that have double underscores.
How can I ensure the final output doesn’t have more than 1 underscore in a row? I know there's probably no Fibery experts here, but figured it was worth a shot...appreciate any help that could be provided.
Don't parse Ls. That seems to work well, but for complex cases it may fail.
With Bash's parameter expansion:
for f in *.mp3; do mv -- "$f" "${f//[!0-9a-zA-Z.-]/_}"; done
With Rename:
rename -- 's/[^0-9a-zA-Z.-]/_/g' *.mp3
If you only have standard POSIX tools and assuming no newline characters in the file names,
for f in *.mp3; do
mv -- "$f" "$(printf '%s\n' "$f" | sed 's/[^0-9a-zA-Z.-]/_/g')"
done
With zsh:
autoload -Uz zmv # best in ~/.zshrc
zmv '(*).mp3' '${f//[^0-9a-zA-Z_.-]/_}'
In zsh, ranges are based on codepoint value, so 0-9 includes 0123456789 only (and not 0123456789٠١٢٣٤٥٦٧٨۰۱۲۳۴۵۶۷۸߀߁߂߃߄߅߆߇߈०१२३४५६७८০১২৩৪৫৬৭৮੦੧੨੩੪੫੬੭੮૦૧૨૩૪૫૬૭૮୦୧୨୩୪୫୬୭୮௦௧௨௩௪௫௬௭௮౦౧౨౩౪౫౬౭౮౸౹౺౻౼౽౾೦೧೨೩೪೫೬೭೮൦൧൨൩൪൫൬൭൮෦෧෨෩෪෫෬෭෮๐๑๒๓๔๕๖๗๘໐໑໒໓໔໕໖໗໘༠༡༢༣༤༥༦༧༨༪༫༬༭༮༯༰༱༳၀၁၂၃၄၅၆၇၈႐႑႒႓႔႕႖႗႘፩፪፫፬፭፮፯፰០១២៣៤៥៦៧៨៰៱៲៳៴៵៶៷៸᠐᠑᠒᠓᠔᠕᠖᠗᠘᥆᥇᥈᥉᥊᥋᥌᥍᥎᧐᧑᧒᧓᧔᧕᧖᧗᧘᧚᪀᪁᪂᪃᪄᪅᪆᪇᪈᪐᪑᪒᪓᪔᪕᪖᪗᪘᭐᭑᭒᭓᭔᭕᭖᭗᭘᮰᮱᮲᮳᮴᮵᮶᮷᮸᱀᱁᱂᱃᱄᱅᱆᱇᱈᱐᱑᱒᱓᱔᱕᱖᱗᱘⁰⁴⁵⁶⁷⁸₀₁₂₃₄₅₆₇₈⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞⅟ↅ↉①②③④⑤⑥⑦⑧⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓾⓿❶❷❸❹❺❻❼❽❿➀➁➂➃➄➅➆➇➉➊➋➌➍➎➏➐➑➓〇〡〢〣〤〥〦〧〨㉈㉉㉊㉋㉌㉍㉎㉏㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿㋀㋁㋂㋃㋄㋅㋆㋇㋉㋊㋋㍘㍙㍚㍛㍜㍝㍞㍟㍠㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㏠㏡㏢㏣㏤㏥㏦㏧㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾꘠꘡꘢꘣꘤꘥꘦꘧꘨꣐꣑꣒꣓꣔꣕꣖꣗꣘꤀꤁꤂꤃꤄꤅꤆꤇꤈꧐꧑꧒꧓꧔꧕꧖꧗꧘꧰꧱꧲꧳꧴꧵꧶꧷꧸꩐꩑꩒꩓꩔꩕꩖꩗꩘꯰꯱꯲꯳꯴꯵꯶꯷꯸012345678𐄇𐄈𐄉𐄊𐄋𐄌𐄍𐄎𐅂𐅃𐅈𐅏𐅘𐅙𐅚𐅛𐅜𐅝𐅞𐅟𐅳𐆊𐋡𐋢𐋣𐋤𐋥𐋦𐋧𐋨𐌠𐌡𐏑𐏒𐒠𐒡𐒢𐒣𐒤𐒥𐒦𐒧𐒨𐡘𐡙𐡚𐡹𐡺𐡻𐡼𐡽𐢧𐢨𐢩𐢪𐢫𐢬𐣻𐣼𐤖𐤚𐤛𐧀𐧁𐧂𐧃𐧄𐧅𐧆𐧇𐩀𐩁𐩂𐩃𐩽𐪝𐫫𐫬𐭘𐭙𐭚𐭛𐭸𐭹𐭺𐭻𐮩𐮪𐮫𐮬𐳺𐳻𐹠𐹡𐹢𐹣𐹤𐹥𐹦𐹧𑁒𑁓𑁔𑁕𑁖𑁗𑁘𑁙𑁦𑁧𑁨𑁩𑁪𑁫𑁬𑁭𑁮𑃰𑃱𑃲𑃳𑃴𑃵𑃶𑃷𑃸𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑇐𑇑𑇒𑇓𑇔𑇕𑇖𑇗𑇘𑇡𑇢𑇣𑇤𑇥𑇦𑇧𑇨𑋰𑋱𑋲𑋳𑋴𑋵𑋶𑋷𑋸𑑐𑑑𑑒𑑓𑑔𑑕𑑖𑑗𑑘𑓐𑓑𑓒𑓓𑓔𑓕𑓖𑓗𑓘𑙐𑙑𑙒𑙓𑙔𑙕𑙖𑙗𑙘𑛀𑛁𑛂𑛃𑛄𑛅𑛆𑛇𑛈𑜰𑜱𑜲𑜳𑜴𑜵𑜶𑜷𑜸𑣠𑣡𑣢𑣣𑣤𑣥𑣦𑣧𑣨𑱐𑱑𑱒𑱓𑱔𑱕𑱖𑱗𑱘𑱚𑱛𑱜𑱝𑱞𑱟𑱠𑱡𒐀𒐁𒐂𒐃𒐄𒐅𒐆𒐈𒐉𒐊𒐋𒐌𒐍𒐏𒐐𒐑𒐒𒐓𒐕𒐖𒐗𒐘𒐙𒐚𒐛𒐜𒐞𒐟𒐠𒐡𒐢𒐣𒐤𒐥𒐦𒐧𒐨𒐩𒐪𒐬𒐭𒐮𒐯𒐰𒐱𒐴𒐵𒐶𒐷𒐸𒐹𒐺𒐻𒐼𒐽𒐾𒐿𒑀𒑁𒑂𒑃𒑄𒑅𒑊𒑋𒑌𒑍𒑎𒑏𒑐𒑑𒑒𒑓𒑔𒑕𒑖𒑗𒑘𒑙𒑩𒑪𒑫𒑬𒑭𖩠𖩡𖩢𖩣𖩤𖩥𖩦𖩧𖩨𖭐𖭑𖭒𖭓𖭔𖭕𖭖𖭗𖭘𝍠𝍡𝍢𝍣𝍤𝍥𝍦𝍧𝟎𝟏𝟐𝟑𝟒𝟓𝟔𝟕𝟖𝟘𝟙𝟚𝟛𝟜𝟝𝟞𝟟𝟠𝟢𝟣𝟤𝟥𝟦𝟧𝟨𝟩𝟪𝟬𝟭𝟮𝟯𝟰𝟱𝟲𝟳𝟴𝟶𝟷𝟸𝟹𝟺𝟻𝟼𝟽𝟾𞣇𞣈𞣉𞣊𞣋𞣌𞣍𞣎𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘🄀🄁🄂🄃🄄🄅🄆🄇🄈🄉🄋🄌🆛🆜🆝🆞🆟🆠🆡🆢🆣🆤 like in bash in most modern locales) and a-z only abcdefghijklmnopqrstuvwxyz (not the thousands of characters other shells would match), but that still done on a per character basis (contrary to what would happened if you switched to the C locale in bash to work around the previous issue where it would work on bytes and break up characters into the bytes constituting there encoding for multibyte ones).
It also doesn't choke on bytes not forming valid characters in the locale (and those bytes would match [^0-9a-zA-Z_.-]), so in the end, the resulting files should only contain characters among 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.-, and no non-character.
In bash, you could do something approaching with:
accepted_characters='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.-'
for f in *[^$accepted_characters]*.mp3; do
mv -i -- "$f" "${f//[^$accepted_characters]/_}"
done
(without the safeguards of zmv).