473,464 Members | 1,516 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

RegExp for hyphen to camelCase?


I'm messing with getPropertyValue (Mozilla et al) and currentStyle (IE)
and have a general function (slightly modified from one originally
posted by Steve van Dongen) for getting style properties:

function GetCurrentStyle( el, prop ) {
if ( window.getComputedStyle ) {
// Mozilla et al
return window.getComputedStyle(el, '').getPropertyValue(prop) );
} // IE5+
else if ( el.currentStyle ) {
return el.currentStyle[prop];
} // IE4
else if ( el.style ) {
return el.style[prop];
}
}

If property names have no hyphen (e.g. width, height) then all is fine.
But with hyphenated names (e.g. margin-right, border-top) Mozilla
wants them unmodified and IE wants them camelCased (marginRight, borderTop).

Is there a simple RegExp that will camelCase hyphenated strings? I can
do it with a loop and string operations but would prefer to use a single
RegExp if possible.

The following works fine using substring (for s having 0 or more
hyphens) but is there a simpler way?

function toCamel ( s ) {
s = s.split('-');
var i=0, j=s.length;
while ( ++i < j ) {
s[0] += s[i].substring(0,1).toUpperCase() + s[i].substring(1);
}
return s[0];
}

I've tried using RegExp but can't get a simple expression without
looping - property names have up to 3 (or more? three-d-light-shadow)
hyphens, a RegExp with global flag should be possible.

Any suggestions?

--
Rob
Jul 23 '05 #1
20 3503
VK


RobG wrote:
I'm messing with getPropertyValue (Mozilla et al) and currentStyle (IE)
and have a general function (slightly modified from one originally
posted by Steve van Dongen) for getting style properties:

function GetCurrentStyle( el, prop ) {
if ( window.getComputedStyle ) {
// Mozilla et al
return window.getComputedStyle(el, '').getPropertyValue(prop) );
} // IE5+
else if ( el.currentStyle ) {
return el.currentStyle[prop];
} // IE4
else if ( el.style ) {
return el.style[prop];
}
}

If property names have no hyphen (e.g. width, height) then all is fine.
But with hyphenated names (e.g. margin-right, border-top) Mozilla
wants them unmodified and IE wants them camelCased (marginRight, borderTop).

Is there a simple RegExp that will camelCase hyphenated strings? I can
do it with a loop and string operations but would prefer to use a single
RegExp if possible.

The following works fine using substring (for s having 0 or more
hyphens) but is there a simpler way?

function toCamel ( s ) {
s = s.split('-');
var i=0, j=s.length;
while ( ++i < j ) {
s[0] += s[i].substring(0,1).toUpperCase() + s[i].substring(1);
}
return s[0];
}

I've tried using RegExp but can't get a simple expression without
looping - property names have up to 3 (or more? three-d-light-shadow)
hyphens, a RegExp with global flag should be possible.

Any suggestions?

--

The pattern search would be simple:

var re = /(-)([a-z])/g;

hyphenString.replace(re,"$2");

This would transform "a-b-c" to "abc"

Unfortunately back to NN4 they have forgotten to include in
JavaScript's RegExp the case transformation sequences (\u and \U). And
so far no one bothered to fix it. So there is no way to transform
"a-b-c" to "aBC" other than using .exec method, pass through all
matches and apply toUpperCase() with string re-assemply each time.

In this case the old charAt/substring method *much* more time/ressource
effective :-(

Jul 23 '05 #2
I would agree with VK's comments.

Taking from both your comments you could try this at least:-

var s="three-d-light-shadow";
var r=/(-)([a-z])/g;
s=s.replace(r,function(a,b,c){return c.toUpperCase();});
alert(s);

Jul 23 '05 #3
fox


RobG wrote:

I'm messing with getPropertyValue (Mozilla et al) and currentStyle (IE)
and have a general function (slightly modified from one originally
posted by Steve van Dongen) for getting style properties:

function GetCurrentStyle( el, prop ) {
if ( window.getComputedStyle ) {
// Mozilla et al
return window.getComputedStyle(el, '').getPropertyValue(prop) );
} // IE5+
else if ( el.currentStyle ) {
return el.currentStyle[prop];
} // IE4
else if ( el.style ) {
return el.style[prop];
}
}

If property names have no hyphen (e.g. width, height) then all is fine.
But with hyphenated names (e.g. margin-right, border-top) Mozilla wants
them unmodified and IE wants them camelCased (marginRight, borderTop).

Is there a simple RegExp that will camelCase hyphenated strings? I can
do it with a loop and string operations but would prefer to use a single
RegExp if possible.

The following works fine using substring (for s having 0 or more
hyphens) but is there a simpler way?

function toCamel ( s ) {
s = s.split('-');
var i=0, j=s.length;
while ( ++i < j ) {
s[0] += s[i].substring(0,1).toUpperCase() + s[i].substring(1);
}
return s[0];
}

I've tried using RegExp but can't get a simple expression without
looping - property names have up to 3 (or more? three-d-light-shadow)
hyphens, a RegExp with global flag should be possible.

Any suggestions?


function
toCamel(s)
{
var re = /(-)(\w)/g;

return s.replace(re,
function(fullmatch,paren1,paren2)
{
return paren2.toUpperCase();
});
}

Jul 23 '05 #4
VK
> var s="three-d-light-shadow";
var r=/(-)([a-z])/g;
s=s.replace(r,function(a,b,c){return c.toUpperCase();});
alert(s);


That's an absolutely cool twist!
Flushing substring !

Jul 23 '05 #5
It does enable you to be quite concise.

Oddly though, I have found that if you use this type of technique on
very large strings, it actually becomes much more inefficient than
ordinary String concatenation or Array joining, by quite a margin. For
a 200k string, String concatenation is about 10x faster. But for small
Strings can be quite useful.

Jul 23 '05 #6
VK
> Oddly though, I have found that if you use this type of technique on
very large strings, it actually becomes much more inefficient than
ordinary String concatenation or Array joining, by quite a margin. For
a 200k string, String concatenation is about 10x faster.


it's not so odd because regexp's are very resource intensive. So on big
texts it takes *a lot*. In some serious implementations of regexp's
there is study() method to "prepare" a large text for regexp
processing.

IE introduced re.compile() method to convert static regexp to binary
code for maximum speed. Did you try that?

Jul 23 '05 #7
>it's not so odd because regexp's are very resource intensive. So on big
texts it takes *a lot*.
I can see how that would be.
I suppose jumping out of the process to call a function will not help
either.
IE introduced re.compile() method to convert static regexp to binary
code for maximum speed. Did you try that?


No I didn't. I'll give it a try. Thanks.

Jul 23 '05 #8
Baconbutty wrote:
I would agree with VK's comments.

Taking from both your comments you could try this at least:-

var s="three-d-light-shadow";
var r=/(-)([a-z])/g;
s=s.replace(r,function(a,b,c){return c.toUpperCase();});
alert(s);


Cool, unfortunately Safari doesn't like it, returning:

threefunction (a, b, c)
{
return c.toUpperCase();
}function (a, b, c)
{
return c.toUpperCase();
}ightfunction (a, b, c)
{
return c.toUpperCase();
}hadow

It is returning the function body rather than the result - similarly
for Fox's suggestion.

So thanks, but I'll have to stick with looping for now. Hopefully
style property names will never reach 200k ;-)
--
Rob
Jul 23 '05 #9
On 21/07/2005 12:39, RobG wrote:
Baconbutty wrote:
[Use a function argument]
Cool, unfortunately Safari doesn't like it, [...]

It is returning the function body rather than the result - similarly for
Fox's suggestion.
So will IE5 and earlier as they don't support function arguments, and
Opera 6 won't perform a replacement at all (a no-op).
So thanks, but I'll have to stick with looping for now. [...]


It takes about 2KB to replace the replace method. :)

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Jul 23 '05 #10
> Cool, unfortunately Safari doesn't like it,
Will IE5 and earlier as they don't support function arguments
Opera 6 won't perform a replacement at all
Thats a shame. It is in the ECMA spec I think, but that is of course
no guarantee that it is implemented everywhere. .
It takes about 2KB to replace the replace method. :)


Perhaps the challenge then is to come up with the most concise
alternative. A starter:-

var a=s.split(""); var b=[]; var j=a.length; var i=0;
do {b[b.length]=(a[i]=="-")?a[++i].toUpperCase():a[i];}while(++i<j)

Jul 23 '05 #11


RobG wrote:

function GetCurrentStyle( el, prop ) {
if ( window.getComputedStyle ) {
// Mozilla et al
return window.getComputedStyle(el, '').getPropertyValue(prop) );
} // IE5+
else if ( el.currentStyle ) {
return el.currentStyle[prop];
} // IE4
else if ( el.style ) {
return el.style[prop];
}
}

If property names have no hyphen (e.g. width, height) then all is fine.
But with hyphenated names (e.g. margin-right, border-top) Mozilla wants
them unmodified and IE wants them camelCased (marginRight, borderTop).


getComputedStyle is supposed to return an object implementing the
CSSStyleDeclaration interface but that interface can optionally be
casted to the CSS2Properties interface which then allows accessing CSS
properties the same way you do with element.style in browsers e.g.
element.style.cssPropertyName
so in Mozilla and Opera you can do
return window.getComputedStyle(el, '')[prop]
if the CSS property name is passed in in camel case (e.g.
'backgroundColor', 'marginRight').
Could you test whether Safari allows that too?

--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #12
On 21/07/2005 14:10, Martin Honnen wrote:

[snip]
so in Mozilla and Opera you can do
return window.getComputedStyle(el, '')[prop]
You could but the global object has never been defined as an instance of
the AbstractView interface. I would use the slightly longer, but
better defined route through the document object:

document.defaultView.getComputedStyle(...)
if the CSS property name is passed in in camel case (e.g.
'backgroundColor', 'marginRight').
Though you should be careful as there is an exception to the case
conversion pattern: float becomes cssFloat.
Could you test whether Safari allows that too?


Neither Safari nor Konqueror support the getComputedStyle method. Though
it exists as a property of the defaultView object in Konqueror, it
always returns null.

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Jul 23 '05 #13


Michael Winter wrote:
On 21/07/2005 14:10, Martin Honnen wrote:
so in Mozilla and Opera you can do
return window.getComputedStyle(el, '')[prop]

You could but the global object has never been defined as an instance of
the AbstractView interface. I would use the slightly longer, but better
defined route through the document object:

document.defaultView.getComputedStyle(...)


Right, I was mainly following Rob's code and only changing the part
after the getComputedStyle. I have myself pointed out that
document.defaultView and window don't have to be the same as far as the
W3C DOM says but as far as Mozilla goes Brendan Eich himself said the
current behaviour is not going to be changed:
<http://groups-beta.google.com/group/netscape.public.mozilla.dom/msg/aa219bf41334c22e?hl=en&>
And the current WHAT WG drafts also try to ensure that the current
praxis that browsers implement document.defaultView as the window object
becomes standardized:
<http://www.whatwg.org/specs/web-apps/current-work/#documentwindow>
so it seems pretty safe to do window.getComputedStyle.

Neither Safari nor Konqueror support the getComputedStyle method. Though
it exists as a property of the defaultView object in Konqueror, it
always returns null.


Ouch, one more case for not only checking for the existance of a method
in the DOM but to check for the result too.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #14
"Baconbutty" <ju****@baconbutty.com> writes:
Perhaps the challenge then is to come up with the most concise
alternative. A starter:-

var a=s.split(""); var b=[]; var j=a.length; var i=0;
do {b[b.length]=(a[i]=="-")?a[++i].toUpperCase():a[i];}while(++i<j)


Overkill (mainly splitting the string into a character array and
looking at each char, not the total size of the snippet). Also
remember to join "b" afterwards.

Anyway:

var p=s.split("-"),i=p.length;
while(--i){p[i]=p[i].charAt(0).toUpperCase()+p[i].substring(1);}
s=p.join("");

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #15
Michael Winter <m.******@blueyonder.co.uk> writes:
It takes about 2KB to replace the replace method. :)


If you don't need full generality, or efficiency, you can do something
like:
---
function replace(string, regexp, func) {
var match, lastMatchEnd=0, res = [];
while((match = regexp.exec(string))) {
var matchString = match[0];
var index = string.indexOf(matchString, lastMatchEnd);
res.push(string.substring(lastMatchEnd, index));
var repl = func.apply(null, match.concat([index, string]));
res.push(String(repl));
lastMatchEnd = index + matchString.length;
}
res.push(string.substring(lastMatchEnd));
return res.join("");
}
---
It should do approximatly the same as string.replace(regexp,func),
assuming that regexp.global is true, in somewhat less than 2K :)

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #16
On 21/07/2005 23:06, Lasse Reichstein Nielsen wrote:
Michael Winter <m.******@blueyonder.co.uk> writes:
It takes about 2KB to replace the replace method. :)
If you don't need full generality, or efficiency, you can do something
like:
---
function replace(string, regexp, func) {
var match, lastMatchEnd=0, res = [];
while((match = regexp.exec(string))) {
var matchString = match[0];
var index = string.indexOf(matchString, lastMatchEnd);


Have you found the index property of the returned array to be unreliable?
res.push(string.substring(lastMatchEnd, index));
If replacement of the replace method is necessary, push...
var repl = func.apply(null, match.concat([index, string]));
....and apply will probably need to be supplied as well (part of my 2KB).
For example, with IE5.

[snip]
assuming that regexp.global is true [...]


The global flag would seem to be a pain; non-existent in IE5 and always
false in early Opera. In those browsers you can match against the string
representation of that object, but I seem to recall Richard saying that
not all browsers would produce a useful value.

[mini rant]
I know that the replace method isn't usually /necessary/ to accomplish a
task, but it would be nice to be able to just call it knowing the darn
thing will work as expected. Oh well, such is browser scripting...
[/mini rant]

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
Jul 23 '05 #17
Michael Winter <m.******@blueyonder.co.uk> writes:
var index = string.indexOf(matchString, lastMatchEnd);
Have you found the index property of the returned array to be unreliable?


Nope, just haven't found it at all :)
If replacement of the replace method is necessary, push... ...and apply will probably need to be supplied as well (part of my
2KB). For example, with IE5.
True. Push is easily replacable:
foo.push(value); ==> foo[foo.length]=value;
but apply is *hard*. It's one of the few valid uses of "eval" that I
have found. However, we don't need to follow the argument structure
of String.prototype.replace as strictly, so it might be better to
use a fixed argument format, e.g. all captures in one array argument:
var repl = func(match[0], match.slice(1), index, string);
[snip]
assuming that regexp.global is true [...]


The global flag would seem to be a pain; non-existent in IE5 and
always false in early Opera.

....

In this case, it's not really the flag itself that is important, but
the behavior of the RegExp on successive calls that it implies.
If that fails, then you will definitly need more plumbing.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #18
> Overkill

On reflection it is.
Also remember to join "b" afterwards.


Oops, fogot to cut and paste that :-o

Jul 23 '05 #19
Martin Honnen wrote:


Michael Winter wrote:
On 21/07/2005 14:10, Martin Honnen wrote:
so in Mozilla and Opera you can do
return window.getComputedStyle(el, '')[prop]

Thanks, I'll use that. No need to add humps of unnecessary code (that
was a really bad pun).

You could but the global object has never been defined as an instance
of the AbstractView interface. I would use the slightly longer, but
better defined route through the document object:

document.defaultView.getComputedStyle(...)

Right, I was mainly following Rob's code and only changing the part
after the getComputedStyle. I have myself pointed out that
document.defaultView and window don't have to be the same as far as the
W3C DOM says but as far as Mozilla goes Brendan Eich himself said the
current behaviour is not going to be changed:
<http://groups-beta.google.com/group/netscape.public.mozilla.dom/msg/aa219bf41334c22e?hl=en&>

And the current WHAT WG drafts also try to ensure that the current
praxis that browsers implement document.defaultView as the window object
becomes standardized:
<http://www.whatwg.org/specs/web-apps/current-work/#documentwindow>
so it seems pretty safe to do window.getComputedStyle.

Neither Safari nor Konqueror support the getComputedStyle method.
Though it exists as a property of the defaultView object in Konqueror,
it always returns null.

Ouch, one more case for not only checking for the existance of a method
in the DOM but to check for the result too.


Agggh, I tested it in Safari (1.0.3) and surprise, Mike is right.
(typeof window.getComputedStyle) returns undefined. Using the code as
posted, Safari falls through to the IE 4 test - el.style - which is
undesirable.

I guess the bottom line is that if you want reliable information about
current element style, everything needs to be applied either inline or
as an element property. Getting CSS style stuff is not reliable.
--
Rob
Jul 23 '05 #20
jscheuer1
2 New Member
I found this thread Googling about looking for more on 'getComputedStyle'. I also found this neat function for it which I have spruced up a bit:
Expand|Select|Wrap|Line Numbers
  1. function getElementStyle(elemID, styleProp, isID) {
  2.     var elem = elemID
  3.     if (isID)
  4.     elem = document.all? document.all[elemID] : document.getElementById(elemID);
  5.     if (elem.currentStyle) {
  6.         return elem.currentStyle[styleProp];
  7.     } else if (window.getComputedStyle) {
  8.         var compStyle = window.getComputedStyle(elem, "");
  9.         return compStyle.getPropertyValue(deCamel(styleProp));
  10.     }
  11.     return "";
  12. }
  13.  
  14. function deCamel (string){
  15. var newString=''
  16. for (var i_tem = 0; i_tem < string.length; i_tem++){
  17. if (string.charCodeAt(i_tem)>=65&&string.charCodeAt(i_tem)<=90)
  18. newString+='-'+string.charAt(i_tem).toLowerCase()
  19. else
  20. newString+=string.charAt(i_tem)
  21. }
  22. return newString
  23. }
So as to be on topic, I also made an 'enCamel' function:
Expand|Select|Wrap|Line Numbers
  1. function enCamel (string){
  2. var newString=''
  3. for (var i_tem = 0; i_tem < string.length; i_tem++){
  4. if (string.charAt(i_tem)=='-'){
  5. newString+=string.charAt(i_tem+1).toUpperCase()
  6. i_tem++
  7. }
  8. else
  9. newString+=string.charAt(i_tem)
  10. }
  11. return newString
  12. }
Withstanding the limitations discussed in the previous posts in this thread, these are still valid methods if used only to deal with specific targeted browsers. For example, when making a script that fades text on Mozilla and IE, a background must be supplied in IE if it doesn't exist. The effect only works in browsers supporting filters, -moz-opacity, or opacity, degrading well in others. For the latter two types the background is a non-issue, for IE, it must be present, if not it can be found and applied by walking up the document tree until one is encountered. An IE specific solution to an IE specific problem.
Sep 27 '05 #21

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: John Benson | last post by:
I never cared for CamelCase because a lot of words in English are compounds, and remembering the right CamelCase rendition of them gets difficult. For example, an object attribute named ...
5
by: Syed Ali | last post by:
Hello, I am trying to create a regexp to express non letters and space. I tried using: var myreg = new RegExp (""); However, it is not working. Basically I want to allow only words with...
27
by: The Bicycling Guitarist | last post by:
Hi. I found the following when trying to learn if there is such a thing as a non-breaking hyphen. Apparently Unicode has a ‑ but that is not well-supported, especially in older browsers. Somebody...
13
by: Matt | last post by:
I would like to set the "list-style-type" to be a hyphen (-). How can I accomplish this in a style sheet. I tried list-style-type: hyphen; and list-style-type: dash; but neither worked. I also...
12
by: Dag Sunde | last post by:
My understanding of regular expressions is rudimentary, at best. I have this RegExp to to a very simple validation of an email-address, but it turns out that it refuses to accept mail-addresses...
4
by: Rubin | last post by:
1) I want to show a breaking hyphen in Mozilla 1.5.0.4 How do I do that? "Unicode standard annex #14", <http://www.unicode.org/reports/tr14/>, defines 4 breaking hyphens. <quote> Breaking...
9
by: Laphan | last post by:
Hi All I'm using the below to limit the input into a text box to just letters, numbers, hyphens and full stops, but I also need to allow the backspace, delete and arrow keys to come through. ...
3
by: durumdara | last post by:
Hi! I want to replace some seqs. in a html. Let: a- b = ab but: xxx -
5
by: gentsquash | last post by:
In a setting where I can specify only a JS regular expression, but not the JS code that will use it, I seek a regexp component that matches a string of letters, ignoring case. E.g, for "cat" I'd...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.