Jak przekonwertować „camelCase” na „Camel Case”?


174

Próbowałem uzyskać polecenie JavaScript regex, aby zamienić coś "thisString"w stylu, "This String"ale najbliższe mi jest zastąpienie litery, co skutkuje czymś w rodzaju "Thi String"lub "This tring". Jakieś pomysły?

Aby wyjaśnić, że potrafię poradzić sobie z prostotą pisania wielkimi literami, po prostu nie jestem tak silny w przypadku wyrażeń regularnych, a dzielenie się "somethingLikeThis"na "something Like This"to, gdzie mam problemy.



6
Jak to jest duplikatem tego. Wszystko, co robi, to zamienianie na wielką literę pierwszego znaku w ciągu, nic bliskiego temu, co chcę zrobić.
A Wizard Did It

Hmm, to nie jest oszustwo pytania, ale wynik może być taki sam. A może nie to chciałeś zrobić? Rozwijać więcej?
superfro

Do ćwiczenia wyrażeń regularnych proponuję RegExr lub Expresso, aby przetestować i po prostu przyjrzeć się wszystkim pytaniom wyrażeń regularnych w SO i spróbować na nie odpowiedzieć. Regeksy nie są najprostszą rzeczą na świecie, ale pamiętaj tylko, że jeśli twoje wyrażenie regularne CIEBIE jest mylące, podziel je i pracuj na części.
josh.trow

Odpowiedzi:


399
"thisStringIsGood"
    // insert a space before all caps
    .replace(/([A-Z])/g, ' $1')
    // uppercase the first character
    .replace(/^./, function(str){ return str.toUpperCase(); })

wyświetlacze

This String Is Good


1
Dobry człowieku, rozdzielam to. Pamiętaj tylko o radach Bobince'a: stackoverflow.com/questions/1732348/…
josh.trow

Czy na pewno jest to zgodne z IE? Właśnie spróbowałem w IETester7 i otrzymałem błąd.
strongriley

3
Dodając również: jeśli masz akronim
składający się z wielkich liter

2
„This” -> „This” (niechciane miejsce na prefiks). Może zmień to na: str.slice (0, 1) .toUpperCase () + str.slice (1) .replace (/ ([AZ]) / g, '$ 1')
Mark Vayngrib

1
@ColdCerberus Możesz użyć: str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() );Konwertuje userIDna User ID, a nawet konwertuje userIDFieldnaUser ID Field
Eugene Mala

87

Byłem tym bezinteresownie zainteresowany, szczególnie w obsłudze sekwencji wielkich liter, na przykład w xmlHTTPRequest. Wymienione funkcje wygenerowałyby „Żądanie Xml HTTP” lub „Żądanie Xml HTTP”, moja daje „Żądanie Xml HTTP”.

function unCamelCase (str){
    return str
        // insert a space between lower & upper
        .replace(/([a-z])([A-Z])/g, '$1 $2')
        // space before last upper in a sequence followed by lower
        .replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
        // uppercase the first character
        .replace(/^./, function(str){ return str.toUpperCase(); })
}

Istnieje również wersja String.prototype w GIST .


To samo można osiągnąć przy 2 wezwaniach do wymiany:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Eugene Mala

22

Można to zwięźle zrobić za pomocą regex lookahead ( demo na żywo ):

function splitCamelCaseToString(s) {
    return s.split(/(?=[A-Z])/).join(' ');
}

(Myślałem, że gflaga (globalna) jest konieczna, ale co dziwne, nie jest w tym konkretnym przypadku).

Używanie lookahead with splitzapewnia, że ​​dopasowana wielka litera nie jest używana i pozwala uniknąć zajmowania się spacją wiodącą, jeśli UpperCamelCase jest czymś, z czym musisz sobie poradzić. Aby zacząć wielką literę każdego z nich, możesz użyć:

function splitCamelCaseToString(s) {
    return s.split(/(?=[A-Z])/).map(function(p) {
        return p.charAt(0).toUpperCase() + p.slice(1);
    }).join(' ');
}

Metoda maptablicowa jest funkcją ES5, ale nadal można jej używać w starszych przeglądarkach z pewnym kodem z MDC . Alternatywnie możesz iterować po elementach tablicy przy użyciu forpętli.


Pierwsza funkcja dzieli go, ale nie PascalCase pierwszego słowa. Druga funkcja nie działa w przypadku braku camelCased. (np .: „id”)
Dementic

16

Myślę, że to powinno być w stanie obsłużyć kolejne wielkie litery, a także proste camelCase.

Na przykład: someVariable => someVariable, ale ABCCode! = ABC Code.

Poniższe wyrażenie regularne działa na Twoim przykładzie, ale jest też typowym przykładem reprezentowania skrótów w camcelCase.

"somethingLikeThis"
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/([A-Z])([a-z])/g, ' $1$2')
    .replace(/\ +/g, ' ') => "something Like This"

"someVariableWithABCCode"
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/([A-Z])([a-z])/g, ' $1$2')
    .replace(/\ +/g, ' ') => "some Variable With ABC Code"

Możesz również dostosować, jak powyżej, aby wykorzystać pierwszy znak.


10
function spacecamel(s){
    return s.replace(/([a-z])([A-Z])/g, '$1 $2');
}

spacecamel („somethingLikeThis”)

// zwrócona wartość: coś takiego


1
Niezłe! to jest dokładnie to, czego potrzebowałem, chciałem podzielić, np .: DiscoveryChannel i HBO inne odpowiedzi dały mi Discovery Channel i HBO, ale Twoja odpowiedź załatwiła sprawę, ponieważ HBO pozostało nienaruszone, dziękuję!
AJS


4

Rozwiązanie, które obsługuje również liczby:

function capSplit(str){
   return str.replace
      ( /(^[a-z]+)|[0-9]+|[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z]|[0-9])/g
      , function(match, first){
          if (first) match = match[0].toUpperCase() + match.substr(1);
          return match + ' ';
          }
       )
   }

Testowane tutaj [JSFiddle, brak biblioteki. Nie próbowano IE]; powinien być dość stabilny.


0

Jeśli nie przejmujesz się starszymi przeglądarkami (lub nie masz nic przeciwko używaniu dla nich funkcji awaryjnej redukcji ), możesz podzielić nawet ciągi znaków, takie jak „xmlHTTPRequest” (ale z pewnością nie da się tego zrobić w przypadku „XMLHTTPRequest”).

function splitCamelCase(str) {
        return str.split(/(?=[A-Z])/)
                  .reduce(function(p, c, i) {
                    if (c.length === 1) {
                        if (i === 0) {
                            p.push(c);
                        } else {
                            var last = p.pop(), ending = last.slice(-1);
                            if (ending === ending.toLowerCase()) {
                                p.push(last);
                                p.push(c);
                            } else {
                                p.push(last + c);
                            }
                        }
                    } else {
                        p.push(c.charAt(0).toUpperCase() + c.slice(1));
                    }
                    return p;
                  }, [])
                  .join(' ');
}

0

Moja wersja

function camelToSpace (txt) {
  return txt
    .replace(/([^A-Z]*)([A-Z]*)([A-Z])([^A-Z]*)/g, '$1 $2 $3$4')
    .replace(/ +/g, ' ')
}
camelToSpace("camelToSpaceWithTLAStuff") //=> "camel To Space With TLA Stuff"

Zastosowałem tę funkcję w pętli na 3000 linii i otrzymałem spacje przed każdą linią zaczynającą się od
dużej

0

Wypróbuj to rozwiązanie tutaj -

var value = "myCamelCaseText";
var newStr = '';
for (var i = 0; i < value.length; i++) {
  if (value.charAt(i) === value.charAt(i).toUpperCase()) {
    newStr = newStr + ' ' + value.charAt(i)
  } else {
    (i == 0) ? (newStr += value.charAt(i).toUpperCase()) : (newStr += value.charAt(i));
  }
}
return newStr;

-5

Nie regex, ale warto znać proste i stare techniki, takie jak ta:

var origString = "thisString";
var newString = origString.charAt(0).toUpperCase() + origString.substring(1);

5
nie, pytanie brzmi „thisString” na „ThisString” (ze spacją), a nie „ThisString”
Pete Kirkham

@rob Jak wstawić spację między „this” a „String”?
ThunderBird
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.