I'm trying to replace uppercase letters with corresponding lowercase letters using regex.
So that
EarTH: 1,
MerCury: 0.2408467,
venuS: 0.61519726,
becomes
earth: 1,
mercury: 0.2408467,
venus: 0.61519726,
in Sublime Text. How can I downcase letters only in words that contain both lower and uppercase letters? So that it affects venUs and not VENUS.
You may:
Find: (\w)
Replace With: \L$1
Or select the text, ctrl+K+L.
I figured this might come in handy for others as well :
find:
([A-Z])(.*)
replace:
\L$1$2 --> will convert all letters in $1 and $2 to lowercase
BUT
\l$1$2 --> will only convert the first letter of $1 to lowercase and leave everything else as is
The same goes for uppercase with \U and \u
Before searching with regex like [A-Z], you should press the case sensitive button (or Alt+C) (as leemour nicely suggested to be edited in the accepted answer). Just to be clear, I'm leaving a few other examples:
Capitalize words
Find: (\s)([a-z]) (\s also matches new lines, i.e. "venuS" => "VenuS")
Replace: $1\u$2
Uncapitalize words
Find: (\s)([A-Z])
Replace: $1\l$2
Remove camel case (e.g. cAmelCAse => camelcAse => camelcase)
Find: ([a-z])([A-Z])
Replace: $1\l$2
Lowercase letters within words (e.g. LowerCASe => Lowercase)
Find: (\w)([A-Z]+)
Replace: $1\L$2
Alternate Replace: \L$0
Uppercase letters within words (e.g. upperCASe => uPPERCASE)
Find: (\w)([A-Z]+)
Replace: $1\U$2
Uppercase previous (e.g. upperCase => UPPERCase)
Find: (\w+)([A-Z])
Replace: \U$1$2
Lowercase previous (e.g. LOWERCase => lowerCase)
Find: (\w+)([A-Z])
Replace: \L$1$2
Uppercase the rest (e.g. upperCase => upperCASE)
Find: ([A-Z])(\w+)
Replace: $1\U$2
Lowercase the rest (e.g. lOWERCASE => lOwercase)
Find: ([A-Z])(\w+)
Replace: $1\L$2
Shift-right-uppercase (e.g. Case => cAse => caSe => casE)
Find: ([a-z\s])([A-Z])(\w)
Replace: $1\l$2\u$3
Shift-left-uppercase (e.g. CasE => CaSe => CAse => Case)
Find: (\w)([A-Z])([a-z\s])
Replace: \u$1\l$2$3
Regarding the question (match words with at least one uppercase and one lowercase letter and make them lowercase), leemour's comment-answer is the right answer. Just to clarify, if there is only one group to replace, you can just use ?: in the inner groups (i.e. non capture groups) or avoid creating them at all:
Find: ((?:[a-z][A-Z]+)|(?:[A-Z]+[a-z])) OR ([a-z][A-Z]+|[A-Z]+[a-z])
Replace: \L$1
2016-06-23 Edit
Tyler suggested by editing this answer an alternate find expression for #4:
(\B)([A-Z]+)
According to the documentation, \B will look for a character that is not at the word's boundary (i.e. not at the beginning and not at the end). You can use the Replace All button and it does the exact same thing as if you had (\w)([A-Z]+) as the find expression.
However, the downside of \B is that it does not allow single replacements, perhaps due to the find's "not boundary" restriction (please do edit this if you know the exact reason).
Try this
Find: ([A-Z])([A-Z]+)\b
Replace: $1\L$2
Make sure case sensitivity is on (Alt + C)
Regular expression
Find:\w+
Replace:\L$0
Sublime Text uses the Perl Compatible Regular Expressions (PCRE)
engine from the Boost library to power regular expressions in search
panels.
\L Converts everything up to lowercase
$0 Capture groups
FIND: (\u)
REPLACE: \L$1$2
Operation confirmed in Notepad++.
Do not forget to check the "Match case" box.
In BBEdit works this (ex.: changing the ID values to lowercase):
Search any value: <a id="(?P<x>.*?)"></a>
Replace with the same in lowercase: <a id="\L\P<x>\E"></a>
Was: <a id="VALUE"></a>
Became: <a id="value"></a>
To convert snake_case words with some additional fields starting with _:
EXAMPLE:
_id
user_name
to
id
userName
Use first:
FIND: (\w)_(\w)
REPLACE: $1\U$2
Then, just replace "_" to "" (Blank space)
Related
I've seen this [a-zA-Z] for the gsub method:
string.gsub(/[a-zA-Z]/,"-")
where it will find any lower case letters a-z and or uppercase letters A-Z.
My question is why does this a-z work back to back with A-Z : a-zA-Z ?
Where might I find more info on using [a-zA-Z] in ruby?
Inside a character class (the [] inside the regex), you can list all the characters you want :
/[abcdefg]/
to gain some space, you can define a range with an hyphen (-) and a letter on each side of the - :
/[a-g]/
Since it's clear that this range is from a to g, you could write another character directly after :
/[a-gm]/
You could also define another range :
/[a-gm-z]/
From the documentation :
A range can be followed by another range, so [abcdwxyz] is equivalent
to [a-dw-z]
Note that for your example, you could also use a case insensitive regex :
string.gsub(/[a-z]/i,"-")
Finally, you can use ranges with unicode characters :
arrows = /[\u2190-\u21FF]/
"a⇸b⇙c↺d↣e↝f".scan(arrows)
# => ["⇸", "⇙", "↺", "↣", "↝"]
I frequently use http://rubular.com/ as a reference
[a-zA-Z] Any single character in the range a-z or A-Z
I am trying to perform regular expression matching and replacement on the same line in Ruby. I have some libraries that manipulate strings in Ruby and add special formatting characters to it. The formatting can be applied in any order. However, if I would like to change the string formatting, I want to keep some of the original formatting. I'm using regex for that. I have the regular expression matching correctly what I need:
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, 'New Text')
However, what I really want is the matching from the first grouping found in:
(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))
to be appended to New Text and replaced as opposed to just New Text. I'm trying to reference the match in the form of
mystring.gsub(/[(\e\[([1-9]|[1,2,4,5,6,7,8]{2}m))|(\e\[[3,9][0-8]m)]*Text/, '\1' + 'New Text')
but my understanding is that \1 only works when using \d or \k. Is there any way to reference that specific capturing group in my replacement string? Additionally, since I am using an asterik for the [], I know that this grouping could occur more than once. Therefore, I would like to have the last matching occurrence yielded.
My expected input/output with a sample is:
Input: "\e[1mHello there\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"
Input: "\e[1mHello there\e[44m\e[34m\e[40mText\e[0m\e[0m\e[22m"
Output: "\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m"
So the last grouping is found and appended.
You can use the following regex with back-reference \\1 in the replacement:
reg = /(\\e\[(?:[0-9]{1,2}|[3,9][0-8])m)+Text/
mystring = "\\e[1mHello there\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
mystring = "\\e[1mHello there\\e[44m\\e[34m\\e[40mText\\e[0m\\e[0m\\e[22m"
puts mystring.gsub(reg, '\\1New Text')
Output of the IDEONE demo:
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
\e[1mHello there\e[40mNew Text\e[0m\e[0m\e[22m
Mind that your input has backslash \ that needs escaping in a regular string literal. To match it inside the regex, we use double slash, as we are looking for a literal backslash.
I need to extract a string 'MT/23232' I have written the below code, but
it's not working, Can any one help me here?
'Policy created with MT/1212'
'Policy created with MT/121212'
'Policy created with MT/21212121212'
I have written this code
msg="MT/33235"
id = msg.scan(/MT/\d+/\d+/)[0]
But it's not working for me, Can any one help me to extract this string?
You need to escape the forward slash which exists next to MT in your regex and you don't need to have a forward slash after \d+ . And also i suggest you to add a lookbehind, so that you get a clean result. (?<=\s) Positive lookbehind which asserts that the match must be preceded by a space character.
msg.scan(/(?<=\s)MT\/\d+/)[0]
If you don't care about the preceding character then the below regex would be fine.
msg.scan(/MT\/\d+/)[0]
Example:
> msg = 'Policy created with MT/21212121212'
=> "Policy created with MT/21212121212"
> msg.scan(/(?<=\s)MT\/\d+/)[0]
=> "MT/21212121212"
> msg.match(/(?<=\s)MT\/\d+/)[0]
=> "MT/21212121212"
your_string.scan(/\sMT.*$/).last.strip
If your required substring can be anywhere in the string, then:
your_string.scan(/\bMT\/\d+\b/).last.strip # "\b" is for word boundaries
Or you can specify the acceptable digits this way:
your_string.scan(/\bMT\/[0-9]+\b/).last.strip
Lastly, if the string format is going to remain as you specified, then:
your_string.split.last
I need the username to be two or more characters of a-z, 0-9, all downcase. This is the current regex I am using
USER_REGEX = /\A[a-z0-9][-a-z0-9]{1,19}\z/i
With this regex, users are able to use uppercase charters in their username. How do I modify the current regex to avoid that?
The regular expression to filter for two to twenty lower-case characters or digits is
/^[a-z0-9]{2,20}$/
which means:
^ at the front of input
a-z accept lower-case 'a' through 'z'
0-9 accept '0' through '9'
{2,20} accept 2 to 20 elements from preceding [] block
$ until the end of input
You can make a regular expression case-insensitive with trailing i, as in your example; that appears to be the root of problem. That said, I don't know Ruby's peculiarities with respect to regular expressions.
If you must keep the RegEx - remove the "i" from the end
USER_REGEX = /\A[a-z0-9][-a-z0-9]{1,19}\z/i
USER_REGEX = /\A[a-z0-9][-a-z0-9]{1,19}\z/
the "i" tells the RegEx to be a case-insensitive RegEx.
but you want it to be case-sensitive and only match on lowercase letters.
I have the following string:
"h3. My Title Goes Here"
I basically want to remove the first four characters from the string so that I just get back:
"My Title Goes Here".
The thing is I am iterating over an array of strings and not all have the h3. part in front so I can't just ditch the first four characters blindly.
I checked the docs and the closest thing I could find was chomp, but that only works for the end of a string.
Right now I am doing this:
"h3. My Title Goes Here".reverse.chomp(" .3h").reverse
This gives me my desired output, but there has to be a better way. I don't want to reverse a string twice for no reason. Is there another method that will work?
To alter the original string, use sub!, e.g.:
my_strings = [ "h3. My Title Goes Here", "No h3. at the start of this line" ]
my_strings.each { |s| s.sub!(/^h3\. /, '') }
To not alter the original and only return the result, remove the exclamation point, i.e. use sub. In the general case you may have regular expressions that you can and want to match more than one instance of, in that case use gsub! and gsub—without the g only the first match is replaced (as you want here, and in any case the ^ can only match once to the start of the string).
You can use sub with a regular expression:
s = 'h3. foo'
s.sub!(/^h[0-9]+\. /, '')
puts s
Output:
foo
The regular expression should be understood as follows:
^ Match from the start of the string.
h A literal "h".
[0-9] A digit from 0-9.
+ One or more of the previous (i.e. one or more digits)
\. A literal period.
A space (yes, spaces are significant by default in regular expressions!)
You can modify the regular expression to suit your needs. See a regular expression tutorial or syntax guide, for example here.
A standard approach would be to use regular expressions:
"h3. My Title Goes Here".gsub /^h3\. /, '' #=> "My Title Goes Here"
gsub means globally substitute and it replaces a pattern by a string, in this case an empty string.
The regular expression is enclosed in / and constitutes of:
^ means beginning of the string
h3 is matched literally, so it means h3
\. - a dot normally means any character so we escape it with a backslash
is matched literally