Convert "ThisIsSomeString" to "this_is_some_string"?

J

Joshua Muheim

Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

Thanks for help,
Joshua
 
A

ara.t.howard

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/
string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?/).reverse.map{|word| word.reverse.downcase}.join '_'
end

def camel_case string
return string if string =~ %r/[A-Z]/ and string !~ %r/_/
words = string.strip.split %r/\s*_+\s*/
words.map!{|w| w.downcase.sub(%r/^./){|c| c.upcase}}
words.join
end

s = "ThisIsSomeString"
p(snake_case(s))

s = "this_is_some_string"
p(camel_case(s))


harp:~ > ruby a.rb
"this_is_some_string"
"ThisIsSomeString"

regards.

-a
 
M

Marcin Mielżyński

Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

Thanks for help,
Joshua

p "ThisIsSomeString".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_')
p "this_is_some_string".split('_').map{|w|w.capitalize}.join

lopex
 
J

Joshua Muheim

Marcin said:
Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

Thanks for help,
Joshua

p "ThisIsSomeString".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_')
p "this_is_some_string".split('_').map{|w|w.capitalize}.join

lopex

syntax error near unexpected token `('

:-(
 
D

Daniel Schierbeck

Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

I believe this is the fastest way, though it may not catch all cases
(numbers and such)

def lowerize(str) # ??
str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
end


Cheers,
Daniel
 
A

ara.t.howard

Joshua said:
Hi all
=20
What's the fastest way to convert "ThisIsSomeString" to=20
"this_is_some_string"?
=20
Thanks for help,
Joshua
=20

p "ThisIsSomeString".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_')
p "this_is_some_string".split('_').map{|w|w.capitalize}.join

irb(main):001:0> "FooBAR".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_')
=3D> "foo"

it's trickier than it looks.


-a
--=20
to foster inner awareness, introspection, and reasoning is more efficient t=
han
meditation and prayer.
- h.h. the 14th dali lama
 
A

ara.t.howard

Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

I believe this is the fastest way, though it may not catch all cases (numbers
and such)

def lowerize(str) # ??
str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
end


Cheers,
Daniel

depending on what you want, the snake_case code i posted works differently:

irb(main):025:0> lowerize 'BARFoo'
=> "barfoo"

irb(main):026:0> snake_case 'BARFoo'
=> "bar_foo"

neither is right - just fyi.

-a
 
M

Marcin Mielżyński

Joshua said:
Marcin said:
Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

Thanks for help,
Joshua
p "ThisIsSomeString".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_')
p "this_is_some_string".split('_').map{|w|w.capitalize}.join

lopex

syntax error near unexpected token `('

:-(

works for me, maybe some typo ?

lopex
 
S

Scott

If you have Rails installed:

require 'action_pack'
"ThisIsSomeString".underscore
=> "this_is_some_string"

-- Scott
 
K

khaines

How about this one?

class MyString < String
def snake_case(group = true)
return self if self == ''
if group
if self =~ /\b(?:[A-Z]+)(?:[A-Z][a-z])/
gsub(/\b([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/\s/,'_').downcase
else
gsub(/([a-zA-Z])([A-Z])/,'\1_\2').gsub(/\s/,'_').downcase
end
else
gsub(/([a-zA-Z])(?=[A-Z])/,'\1_\2').gsub(/\s/,'_').downcase
end
end
end

a = MyString.new("fooBar")
puts a.snake_case
b = MyString.new("FOOBar")
puts b.snake_case
c = MyString.new("FOOOOBar")
puts c.snake_case


When ran:

foo_bar
foo_bar
foooo_bar


Kirk Haines
 
D

Daniel Schierbeck

Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

I believe this is the fastest way, though it may not catch all cases
(numbers and such)

def lowerize(str) # ??
str.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
end


Cheers,
Daniel

depending on what you want, the snake_case code i posted works differently:

irb(main):025:0> lowerize 'BARFoo'
=> "barfoo"

irb(main):026:0> snake_case 'BARFoo'
=> "bar_foo"

neither is right - just fyi.

Correct. Your solution has a flaw, too.

"fooBar".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_') => "bar"

Lets see if we can solve this without peeking at the Rails source :)


Cheers,
Daniel
 
A

ara.t.howard

depending on what you want, the snake_case code i posted works differently:

irb(main):025:0> lowerize 'BARFoo'
=> "barfoo"

irb(main):026:0> snake_case 'BARFoo'
=> "bar_foo"

neither is right - just fyi.

Correct. Your solution has a flaw, too.

"fooBar".scan(/[A-Z][a-z]+/).map{|w|w.downcase}.join('_') => "bar"

good catch!
Lets see if we can solve this without peeking at the Rails source :)

here's a start:

harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/
string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/).reverse.map{|word| word.reverse.downcase}.join '_'
end

def camel_case string
return string if string =~ %r/[A-Z]/ and string !~ %r/_/
words = string.strip.split %r/\s*_+\s*/
words.map!{|w| w.downcase.sub(%r/^./){|c| c.upcase}}
words.join
end

if $0 == __FILE__
require 'test/unit'
require 'enumerator'

class T < Test::Unit::TestCase
tests = {
"snake_case" => %w[
ThisIsSomeString this_is_some_string
fooBar foo_bar
FooBar foo_bar
Foo foo
],

"camel_case" => %w[
this_is_some_string ThisIsSomeString
foo_bar FooBar
foo Foo
foo_bar_foobar FooBarFoobar
]
}

tests.each do |meth, list|
testno = -1
list.each_slice(2) do |arg, expected|
define_method "test_#{ meth }_#{ testno += 1 }" do
actual = send meth, arg
assert_equal expected, actual
end
end
end
end
end


harp:~ > ruby a.rb
Loaded suite a
Started
........
Finished in 0.001527 seconds.

8 tests, 8 assertions, 0 failures, 0 errors


cheers.

-a
 
W

William James

Joshua said:
Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

Thanks for help,
Joshua

p ["FooBar","fooBar","FOOBar","FooBAR"].map{|s|
s.gsub(/.(?=[A-Z])/,'\&_').downcase }

["foo_bar", "foo_bar", "f_o_o_bar", "foo_b_a_r"]
 
D

Daniel Schierbeck

here's a start:

harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/

string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/).reverse.map{|word|
word.reverse.downcase}.join '_'
end

Can we agree that "ABCde" => "ab_cde"?

I still get an error when the original string has underscores in it:

"foo_Bar" => "foo__bar"
"foo_BAR" => "foo__bar"

Too tired to figure out a solution right now, I'll get back to you in
the morning (that'll probably be your night.)


Cheers,
Daniel
 
A

ara.t.howard

here's a start:

harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/
string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/).reverse.map{|word|
word.reverse.downcase}.join '_'
end

Can we agree that "ABCde" => "ab_cde"?

sure. it's arbitrary i realize - but i make sense to me! ;-)
I still get an error when the original string has underscores in it:

"foo_Bar" => "foo__bar"
"foo_BAR" => "foo__bar"

Too tired to figure out a solution right now, I'll get back to you in the
morning (that'll probably be your night.)

ok. i actually use this method in some production code so a better impl would
be nice!

here's the latest, which fixes bug above:

harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/
reversed_words = string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map{|word| word.reverse.downcase}.join('_').gsub(%r/_+/,'_')
end

def camel_case string
return string if string =~ %r/[A-Z]/ and string !~ %r/_/
words = string.strip.split %r/\s*_+\s*/
words.map!{|w| w.downcase.sub(%r/^./){|c| c.upcase}}
words.join
end

if $0 == __FILE__
require 'test/unit'
require 'enumerator'

class T < Test::Unit::TestCase
tests = {
"snake_case" => %w[
ThisIsSomeString this_is_some_string
fooBar foo_bar
FooBar foo_bar
Foo foo
Foo_Bar foo_bar
foo_Bar foo_bar
foo_BAR foo_bar
],

"camel_case" => %w[
this_is_some_string ThisIsSomeString
foo_bar FooBar
foo Foo
foo_bar_foobar FooBarFoobar
]
}

tests.each do |meth, list|
testno = -1
list.each_slice(2) do |arg, expected|
define_method "test_#{ meth }_#{ testno += 1 }" do
actual = send meth, arg
assert_equal expected, actual
end
end
end
end
end


harp:~ > ruby a.rb
Loaded suite a
Started
...........
Finished in 0.003574 seconds.

11 tests, 11 assertions, 0 failures, 0 errors


-a
 
L

Logan Capaldo

Hi all

What's the fastest way to convert "ThisIsSomeString" to
"this_is_some_string"?

Thanks for help,
Joshua

I like to do string.split(/(?=[A-Z])/).map { |s| s.downcase }.join('_')
 
D

Daniel Schierbeck

def snake_case string
return string unless string =~ %r/[A-Z]/
reversed_words = string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map{|word|
word.reverse.downcase}.join('_').gsub(%r/_+/,'_')

I'm not sure you want to label these as bugs:

"FOO_Bar" => "fo_o_bar"
"FOO_bar" => "fo_o_bar"

But this probably is:

"FOO_BAR" => "fo_o_bar"


Cheers,
Daniel
 
D

Daniel Schierbeck

Daniel said:
def snake_case string
return string unless string =~ %r/[A-Z]/
reversed_words = string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map{|word|
word.reverse.downcase}.join('_').gsub(%r/_+/,'_')

This is what I got:



class String
def snake_case
return self unless self =~ /[A-Z]/
split('_').map do |part|
break "" if part.empty?
reversed_words = part.reverse.scan(/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map do |word|
word.reverse.downcase
end.join('_')
end.join('_')
end
end

if $0 == __FILE__
require 'test/unit'

class SnakeCaseTest < Test::Unit::TestCase
i = 0

%w{Foo_bar Foo_Bar FOO_Bar FOO_bar FOO_BAR foo_Bar
fooBar FooBar FooBAR FOOBar}.each do |str|
define_method("test_#{i += 1}") do
assert_equal "foo_bar", str.snake_case,
"could not handle #{str}"
end
end

%w{_foobar __foobar _foobar_ __foobar__
foo_bar _foo_bar_ __foo_bar__}.each do |str|
define_method("test_#{i += 1}") do
assert_equal str, str.snake_case
end
end
end
end


Cheers,
Daniel
 
A

ara.t.howard

Daniel said:
def snake_case string
return string unless string =~ %r/[A-Z]/
reversed_words = string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map{|word|
word.reverse.downcase}.join('_').gsub(%r/_+/,'_')

This is what I got:
<snip and integrate into my test>

this is what i have - anyone have improvments? comments on camel_case?

harp:~ > cat a.rb
def snake_case string
return string unless string =~ /[A-Z]/
string.split('_').map do |part|
break "" if part.empty?
reversed_words = part.reverse.scan(/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map do |word|
word.reverse.downcase
end.join('_')
end.join('_')
end

def camel_case string
return string if string =~ %r/[A-Z]/ and string !~ %r/_/
words = string.strip.split %r/\s*_+\s*/
words.map!{|w| w.downcase.sub(%r/^./){|c| c.upcase}}
words.join
end

if $0 == __FILE__
require 'test/unit'
require 'enumerator'

class T < Test::Unit::TestCase
tests = {
"snake_case" => %w[
ThisIsSomeString this_is_some_string
FOOBar foo_bar
FOO_BAR foo_bar
FOO_Bar foo_bar
FOO_bar foo_bar
Foo foo
FooBAR foo_bar
FooBar foo_bar
Foo_Bar foo_bar
Foo_bar foo_bar
fooBar foo_bar
foo_BAR foo_bar
foo_Bar foo_bar
],

"camel_case" => %w[
foo Foo
foo_bar FooBar
foo_bar_foobar FooBarFoobar
this_is_some_string ThisIsSomeString
]
}

tests.each do |meth, list|
testno = -1
list.each_slice(2) do |arg, expected|
define_method "test_#{ meth }_#{ testno += 1 }" do
actual = send meth, arg
assert_equal expected, actual
end
end
end
end
end


harp:~ > ruby a.rb
Loaded suite snake_camel
Started
.................
Finished in 0.002831 seconds.

17 tests, 17 assertions, 0 failures, 0 errors


thanks for the input!

cheers.

-a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,209
Messages
2,571,089
Members
47,689
Latest member
kilaocrhtbfnr

Latest Threads

Top