IT story

지정된 문자의 첫 번째 인스턴스에서만 문자열 분리

hot-time 2020. 4. 15. 12:36
반응형

지정된 문자의 첫 번째 인스턴스에서만 문자열 분리


내 코드에서는 _배열을 기반으로 문자열을 분할 하고 두 번째 항목을 가져옵니다.

var element = $(this).attr('class');
var field = element.split('_')[1];

소요 good_luck와 저를 제공합니다 luck. 잘 작동합니다!

그러나 이제는 다음과 같은 클래스가 good_luck_buddy있습니다. Javascript에서 두 번째를 무시하고 _나에게 luck_buddy어떻게 주어야 합니까?

var field = element.split(new char [] {'_'}, 2);ac # stackoverflow 답변 에서 이것을 찾았 지만 작동하지 않습니다. jsFiddle에서 다시 시도했습니다 ...


캡처 괄호를 사용하십시오 .

"good_luck_buddy".split(/_(.+)/)[1]
"luck_buddy"

그들은 다음과 같이 정의됩니다

separator캡처 괄호가 포함 된 경우 일치하는 결과가 배열에 반환됩니다.

따라서이 경우에는 우리는에 분할 할 _.+(즉, 분할 구분 하위 문자열로 시작되는 _) 뿐만 아니라 결과가 우리 분리기의 일부 (예를 포함 할 수 있도록 모든 후를 _).

이 예에서 구분 기호 (일치 _(.+))는 _luck_buddy캡처 된 그룹 (구분 기호 내)입니다 lucky_buddy. 캡처 괄호가 없으면 luck_buddy(matching .+)은 결과 split에 구분 기호가 포함되지 않은 간단한 결과 배열에 포함되지 않습니다.


정규 표현식과 배열에는 무엇이 필요합니까?

myString = myString.substring(myString.indexOf('_')+1)

var myString= "hello_there_how_are_you"
myString = myString.substring(myString.indexOf('_')+1)
console.log(myString)


모든 비용으로 RegExp를 피합니다. 할 수있는 또 다른 일이 있습니다.

"good_luck_buddy".split('_').slice(1).join('_')

첫 번째 인스턴스를 고유 한 자리 표시 자로 바꾸고 거기서 분리하십시오.

"good_luck_buddy".replace(/\_/,'&').split('&')

["good","luck_buddy"]

이것은 분할의 양쪽이 필요할 때 더 유용합니다.


정규식을 다음과 같이 사용할 수 있습니다.

var arr = element.split(/_(.*)/)
분할 한계를 지정하는 두 번째 매개 변수를 사용할 수 있습니다. 즉 : var field = element.split ( '_', 1) [1];

String.split불행히도 Javascript 는 실제 분할 수를 제한 할 방법이 없습니다. 반환되는 실제 분할 항목 수를 지정하는 두 번째 인수가 있으므로 귀하의 경우에는 유용하지 않습니다. 해결책은 문자열을 분할하고 첫 번째 항목을 끈 다음 나머지 항목을 다시 결합하는 것입니다.

var element = $(this).attr('class');
var parts = element.split('_');

parts.shift(); // removes the first item from the array
var field = parts.join('_');

문자열의 두 부분이 필요하므로 정규식 lookbehind가 도움이됩니다.

const full_name = 'Maria do Bairro';
const [first_name, last_name] = full_name.split(/(?<=^[^ ]+) /);
console.log(first_name);
console.log(last_name);


Mark F의 솔루션은 훌륭하지만 이전 브라우저에서는 지원되지 않습니다. Kennebec의 솔루션은 이전 브라우저에서 훌륭하고 지원되지만 정규식은 지원하지 않습니다.

따라서 문자열을 한 번만 분할하여 이전 브라우저에서 지원하고 정규식을 지원하는 솔루션을 찾고 있다면 여기 내 솔루션이 있습니다.

String.prototype.splitOnce = function(regex)
{
    var match = this.match(regex);
    if(match)
    {
        var match_i = this.indexOf(match[0]);
        
        return [this.substring(0, match_i),
        this.substring(match_i + match[0].length)];
    }
    else
    { return [this, ""]; }
}

var str = "something/////another thing///again";

alert(str.splitOnce(/\/+/)[1]);


정규 표현식에 익숙하지 않은 저와 같은 초보자에게는이 해결 방법이 효과적이었습니다.

   var field = "Good_Luck_Buddy";
   var newString = field.slice( field.indexOf("_")+1 );

slice () 메서드는 문자열의 일부를 추출하여 새 문자열을 반환하고 indexOf () 메서드는 문자열에서 지정된 값이 처음 발견 된 위치를 반환합니다.


이것은 Chrome + FF에서 나를 위해 일했습니다.

"foo=bar=beer".split(/^[^=]+=/)[1] // "bar=beer"
"foo==".split(/^[^=]+=/)[1] // "="
"foo=".split(/^[^=]+=/)[1] // ""
"foo".split(/^[^=]+=/)[1] // undefined

키가 필요한 경우 다음을 시도하십시오.

"foo=bar=beer".split(/^([^=]+)=/) // Array [ "", "foo", "bar=beer" ]
"foo==".split(/^([^=]+)=/) // [ "", "foo", "=" ]
"foo=".split(/^([^=]+)=/) // [ "", "foo", "" ]
"foo".split(/^([^=]+)=/) // [ "foo" ]

//[0] = ignored (holds the string when there's no =, empty otherwise)
//[1] = hold the key (if any)
//[2] = hold the value (if any)

트릭을 수행하는 하나의 RegExp이 있습니다.

'good_luck_buddy' . split(/^.*?_/)[1] 

먼저 '^'로 시작부터 일치를 시작합니다. 그런 다음 '_'이 아닌 모든 문자, 즉 첫 번째 '_'앞의 모든 문자와 일치합니다.

'?' 전체 패턴을 일치시키는 최소 문자 수는 '. *?' 그 뒤에 '_'가 오므로 마지막 문자로 경기에 포함됩니다.

따라서이 split ()은 일치하는 부분을 '스플리터'로 사용하여 결과에서 제거합니다. 따라서 첫 번째 '_'까지 모든 것을 제거하고 결과의 두 번째 요소로 나머지를 제공합니다. 첫 번째 요소는 일치하는 부분 앞의 부분을 나타내는 ""입니다. 경기는 처음부터 시작하기 때문에 ""입니다.

이전 답변에서 Chandu가 제공 한 /_(.*)/와 같이 작동하는 다른 RegExps가 있습니다.

/^.*?_/는 그룹이 replace ()를 사용하여 수행하는 특수 역할 캡처에 대해 알 필요없이 그 기능을 이해할 수 있다는 이점이 있습니다.


가장 빠른 솔루션?

나는 몇 가지 벤치 마크를 실행 했으며이 솔루션은 크게 승리했습니다. 1

str.slice(str.indexOf(delim) + delim.length)

// as function
function gobbleStart(str, delim) {
    return str.slice(str.indexOf(delim) + delim.length);
}

// as polyfill
String.prototype.gobbleStart = function(delim) {
    return this.slice(this.indexOf(delim) + delim.length);
};

다른 솔루션과의 성능 비교

유일하게 가까운 경쟁자는을 substr대신 사용 하는 것을 제외하고는 동일한 코드 줄 이었습니다 split.

내가 관련된 노력 다른 솔루션 split또는 RegExp의 큰 성능 저하를 가져다가 2 개에 대해 하였다 크기 순서 느린. 물론 join의 결과를 사용 split하면 추가 성능 저하가 추가됩니다.

왜 느려요? 새로운 객체 나 배열을 만들 때마다 JS는 OS에 메모리 청크를 요청해야합니다. 이 과정은 매우 느립니다.

벤치 마크를 쫓는 경우를위한 일반적인 지침은 다음과 같습니다.

  • 객체 {}나 어레이에 대한 새로운 동적 메모리 할당 []( split생성 하는 것과 같은 )은 많은 비용이 들게됩니다.
  • RegExp 검색은 문자열 검색보다 복잡하고 느립니다.
  • 이미 배열이있는 경우 배열을 파괴하는 것은 명시 적으로 색인을 생성하는 것만 큼 빠르며 멋지게 보입니다.

첫 번째 인스턴스를 넘어서 제거

다음은 n 번째 인스턴스까지 슬라이스하는 솔루션입니다. 빠르지는 않지만 OP의 질문에 따르면 gobble(element, '_', 1)여전히 a RegExp또는 split솔루션 보다 2 배 이상 빠르며 더 많은 작업을 수행 할 수 있습니다.

/*
`gobble`, given a positive, non-zero `limit`, deletes
characters from the beginning of `haystack` until `needle` has
been encountered and deleted `limit` times or no more instances
of `needle` exist; then it returns what remains. If `limit` is
zero or negative, delete from the beginning only until `-(limit)`
occurrences or less of `needle` remain.
*/
function gobble(haystack, needle, limit = 0) {
  let remain = limit;
  if (limit <= 0) { // set remain to count of delim - num to leave
    let i = 0;
    while (i < haystack.length) {
      const found = haystack.indexOf(needle, i);
      if (found === -1) {
        break;
      }
      remain++;
      i = found + needle.length;
    }
  }

  let i = 0;
  while (remain > 0) {
    const found = haystack.indexOf(needle, i);
    if (found === -1) {
      break;
    }
    remain--;
    i = found + needle.length;
  }
  return haystack.slice(i);
}

위의 정의를 사용하면 gobble('path/to/file.txt', '/')파일 이름을 지정 gobble('prefix_category_item', '_', 1)하고이 답변의 첫 번째 솔루션과 같은 접두사를 제거합니다.


  1. 테스트는 macOSX 10.14의 Chrome 70.0.3538.110에서 실행되었습니다.

정규식replace() 과 함께 문자열 메서드를 사용하십시오 .

var result = "good_luck_buddy".replace(/.*?_/, "");
console.log(result);

이 정규식은 전에 먼저 0 개 이상의 문자와 일치 _하고, _그 자체. 그런 다음 일치 항목이 빈 문자열로 바뀝니다.

참고 URL : https://stackoverflow.com/questions/4607745/split-string-only-on-first-instance-of-specified-character

반응형