자바 스크립트에서 문자열을 여러 구분 기호로 어떻게 분할합니까?


504

JavaScript에서 문자열을 여러 구분 기호로 분리하려면 어떻게합니까? 쉼표와 공백으로 분할하려고하지만 JS의 분할 기능은 하나의 구분 기호 만 지원합니다.


3
이 문제는 Windows에서 nodejs로 구성된 파일 경로를 분할하려고했습니다. 같은 경로에 때때로 "/"와 "\"슬래시가있었습니다.
Fuhrmanator

답변:


707

정규 표현식을 매개 변수로 전달하십시오.

js> "Hello awesome, world!".split(/[\s,]+/)
Hello,awesome,world!

추가하기 위해 편집 :

배열의 길이에서 1을 뺀 값을 선택하면 마지막 요소를 얻을 수 있습니다.

>>> bits = "Hello awesome, world!".split(/[\s,]+/)
["Hello", "awesome", "world!"]
>>> bit = bits[bits.length - 1]
"world!"

... 패턴이 일치하지 않는 경우 :

>>> bits = "Hello awesome, world!".split(/foo/)
["Hello awesome, world!"]
>>> bits[bits.length - 1]
"Hello awesome, world!"

1
js> 콘솔에 무엇을 사용하고 있습니까?
핵심

4
rhino, Java에서 Mozilla의 JavaScript 구현 : mozilla.org/rhino (... 또는 "sudo apt-get install rhino").
Aaron Maenpaa

감사. 내가해야 할 일과 관련된 또 다른 질문은 분할 된 배열의 마지막 요소를 얻는 것입니다. 배열이 없으면 문자열 thx를 반환해야합니다

2
정규식으로 분할 할 때 구분 기호를 제거하지 않는 방법이 있습니까?
Anderson Green

파이프 기호와 같은 다른 문자 (또는 다른 정규식)뿐만 아니라 문자열 "hello world"로 분할하는 방법은 무엇입니까? 시도한 변형이 (hello world)|\|아직 효과가 없었습니다. 어떤 아이디어?
natty 약 nutty

183

정규식을 Javascript의 split 연산자 로 전달할 수 있습니다 . 예를 들면 다음과 같습니다.

"1,2 3".split(/,| /) 
["1", "2", "3"]

또는 여러 구분 기호를 함께 사용하여 하나의 역할 만하도록하려면

"1, 2, , 3".split(/(?:,| )+/) 
["1", "2", "3"]

(그렇지 않으면 캡처되지 않는 (? :) 구문을 사용해야합니다. 그렇지 않으면 결과에 다시 연결되기 때문입니다. 또는 Aaron처럼 영리하고 문자 클래스를 사용할 수 있습니다.)

(Safari + FF에서 테스트 한 예)


3
"one; #two; #new jersey"와 같이 하나의 역할을하는 여러 문자가 필요한 경우 문자열 "; #"을 split 함수에 전달하면됩니다. "one; #two; #new jersey".split ( "; #") [2] === "new jersey"
Oskar Austegard

이 방법은 하나 이상의 문자로 분할해야하는 경우 문자 클래스보다 더 효과적입니다. |Jesse가 보여 주듯이 분리하십시오 .
devios1

정규 표현식으로 문자열을 분할 할 때 구분 기호를 제거하지 않는 방법이 있는지 궁금합니다.이 예제는 구분 기호를 제거하지만 문자열을 제거하지 않고 분할 할 수 있기를 바랍니다.
Anderson Green

1
@AndersonGreen 그것은 당신이 원하는 것에 정확히 달려 있습니다. 이 경우 여러 구분 기호가 있으므로 모든 구분 기호를 유지 하시겠습니까? 별도 품목으로? 이전 항목에 가입 했습니까? 다음 아이템? 분명하지 않은 것 같습니다. 찾고있는 몇 가지 예를 통해 새로운 질문을하고 싶을 수도 있습니다.
Jesse Rusak

@JesseRusak 모든 구분 기호를 별도의 항목으로 유지하여 구분 기호 목록을 사용하여 문자열을 토큰 화 할 수있었습니다.
Anderson Green

55

간단하지만 효과적인 또 다른 방법은 split + join을 반복적으로 사용하는 것입니다.

"a=b,c:d".split('=').join(',').split(':').join(',').split(',')

본질적으로 split 다음에 join을 수행하는 것은 전역 바꾸기와 비슷하므로 각 구분 기호를 쉼표로 바꾼 다음 모두 바꾸면 쉼표에서 마지막으로 분할됩니다

위 식의 결과는 다음과 같습니다.

['a', 'b', 'c', 'd']

이것을 확장하면 함수에 배치 할 수도 있습니다.

function splitMulti(str, tokens){
        var tempChar = tokens[0]; // We can use the first token as a temporary join character
        for(var i = 1; i < tokens.length; i++){
            str = str.split(tokens[i]).join(tempChar);
        }
        str = str.split(tempChar);
        return str;
}

용법:

splitMulti('a=b,c:d', ['=', ',', ':']) // ["a", "b", "c", "d"]

이 기능을 많이 사용하면 String.prototype.split편의를 위해 줄 바꿈 을 고려해 볼 가치가 있습니다 (내 기능이 상당히 안전하다고 생각합니다-유일한 고려 사항은 조건부 (사소한)의 추가 오버 헤드와 한계 인수의 구현이 없다는 사실입니다 배열이 전달되면).

splitMulti아래 에이 접근법을 사용하여 단순히 감싸는 경우 함수 를 포함시켜야합니다 . :). 또한 일부 사람들은 내장 기능을 확장하는 것에 싫증이 나기 때문에 (많은 사람들이 잘못하고 갈등이 발생할 수 있음) 의심 스러우면 이것을 사용하기 전에 더 고위 사람과 이야기하거나 SO에게 물어보십시오.)

    var splitOrig = String.prototype.split; // Maintain a reference to inbuilt fn
    String.prototype.split = function (){
        if(arguments[0].length > 0){
            if(Object.prototype.toString.call(arguments[0]) == "[object Array]" ) { // Check if our separator is an array
                return splitMulti(this, arguments[0]);  // Call splitMulti
            }
        }
        return splitOrig.apply(this, arguments); // Call original split maintaining context
    };

용법:

var a = "a=b,c:d";
    a.split(['=', ',', ':']); // ["a", "b", "c", "d"]

// Test to check that the built-in split still works (although our wrapper wouldn't work if it didn't as it depends on it :P)
        a.split('='); // ["a", "b,c:d"] 

즐겨!


3
왜 쓰는가 for(var i = 0; i < tokens.length; i++)하지 for(var i = 1; i < tokens.length; i++)?
tic

나는 그 최적화를 놓쳤다. 당신은 우리가 tokens[1]하나의 반복을 저장하기 시작할 수 tokens[0] == tempchar있고, 우리는 마무리하기 위해 tempchar반복 한 후에 분할 tokens할 수 있습니다. @tic :) 감사합니다.
브라이언

20

간단하게 유지할 수 있습니다. (RegEx에 "[] +"추가는 "1 이상"을 의미합니다.)

이는 "+"와 "{1,}"이 동일 함을 의미합니다.

var words = text.split(/[ .:;?!~,`"&|()<>{}\[\]\r\n/\\]+/); // note ' and - are kept

2
끝에 "+"를 추가하면 1 이상을 의미합니다
Asher

6
나는 이것이 간단하지 않고 최소한이라고 말하고 싶다
Darryl Hebbes

+ 및-:-D의 경우 공백 문자 대신 \ s : var words = text.split (/ [\ s.:;?!~,`"&|()<>{}\= \ + \-[] \ r \ n / \] + /);
Didier68

12

까다로운 방법 :

var s = "dasdnk asd, (naks) :d skldma";
var a = s.replace('(',' ').replace(')',' ').replace(',',' ').split(' ');
console.log(a);//["dasdnk", "asd", "naks", ":d", "skldma"]

3
:/

1
당신은 변경할 수 있습니다 '('에 대한 /(/g모든 대체 할 (요소를 - g는 IS 글로벌 정규식을위한 플래그 -이 모든 항목을 검색 할 수 있도록 (하지 첫 번째
codename-

7

분할 기능에서 더 많은 사용자 정의를 원하는 사람들을 위해 주어진 문자열을 분할 할 문자 목록으로 분할하는 재귀 알고리즘을 작성했습니다. 위의 게시물을보기 전에 이것을 썼습니다. 좌절 한 프로그래머에게 도움이되기를 바랍니다.

splitString = function(string, splitters) {
    var list = [string];
    for(var i=0, len=splitters.length; i<len; i++) {
        traverseList(list, splitters[i], 0);
    }
    return flatten(list);
}

traverseList = function(list, splitter, index) {
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != list[index].split(splitter)) ? list[index] = list[index].split(splitter) : null;
        (list[index].constructor === Array) ? traverseList(list[index], splitter, 0) : null;
        (list.constructor === Array) ? traverseList(list, splitter, index+1) : null;    
    }
}

flatten = function(arr) {
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? flatten(val) : val);
    },[]);
}

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
splitString(stringToSplit, splitList);

위의 예는 다음을 반환합니다. ["people", "and", "other", "things"]

참고 : flatten기능은 Rosetta Code 에서 가져 왔습니다.


6

분리 자로 사용하려는 모든 문자를 단수 또는 집합 적으로 정규식으로 묶어 split 함수에 전달할 수 있습니다. 예를 들어 다음과 같이 쓸 수 있습니다.

console.log( "dasdnk asd, (naks) :d skldma".split(/[ \(,\)]+/) );

출력은 다음과 같습니다.

["dasdnk", "asd", "naks", ":d", "skldma"]

3

아마도 하나의 구분 기호를 다른 구분 기호로 바꾸려면 일종의 문자열 바꾸기를 수행해야하므로 분할에서 처리 할 하나의 구분 기호 만 있어야합니다.


3

예를 들어 String 07:05:45 PM에서 나누고 교체 한 경우 안녕

var hour = time.replace("PM", "").split(":");

결과

[ '07', '05', '45' ]

3

ES6 에서이를 달성하는 새로운 방법은 다음과 같습니다 .

function SplitByString(source, splitBy) {
  var splitter = splitBy.split('');
  splitter.push([source]); //Push initial value

  return splitter.reduceRight(function(accumulator, curValue) {
    var k = [];
    accumulator.forEach(v => k = [...k, ...v.split(curValue)]);
    return k;
  });
}

var source = "abc,def#hijk*lmn,opq#rst*uvw,xyz";
var splitBy = ",*#";
console.log(SplitByString(source, splitBy));

이 기능에 유의하십시오 :

  • 정규식이 없습니다.
  • 표시된 순서대로 분할 된 값을 반환합니다 source

위 코드의 결과는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


2
a = "a=b,c:d"

array = ['=',',',':'];

for(i=0; i< array.length; i++){ a= a.split(array[i]).join(); }

특수 문자없이 문자열을 반환합니다.


2

@Brian 답변의 리 팩터

var string = 'and this is some kind of information and another text and simple and some egample or red or text';
var separators = ['and', 'or'];

function splitMulti(str, separators){
            var tempChar = 't3mp'; //prevent short text separator in split down
            
            //split by regex e.g. \b(or|and)\b
            var re = new RegExp('\\b(' + separators.join('|') + ')\\b' , "g");
            str = str.replace(re, tempChar).split(tempChar);
            
            // trim & remove empty
            return str.map(el => el.trim()).filter(el => el.length > 0);
}

console.log(splitMulti(string, separators))


1

필자가 필요한 주된 이유 중 하나는 /및 에서 파일 경로를 분할하는 것 \입니다. 약간 까다로운 정규 표현식이므로 참조를 위해 여기에 게시 할 것입니다.

var splitFilePath = filePath.split(/[\/\\]/);

1

제거하고 싶은 것이 아니라 떠나고 싶은 것을 지정하면 더 쉽다고 생각합니다.

영어 단어 만 갖고 싶은 것처럼 다음과 같이 사용할 수 있습니다.

text.match(/[a-z'\-]+/gi);

예 (스 니펫 실행) :

var R=[/[a-z'\-]+/gi,/[a-z'\-\s]+/gi];
var s=document.getElementById('s');
for(var i=0;i<R.length;i++)
 {
  var o=document.createElement('option');
  o.innerText=R[i]+'';
  o.value=i;
  s.appendChild(o);
 }
var t=document.getElementById('t');
var r=document.getElementById('r');

s.onchange=function()
 {
  r.innerHTML='';
  var x=s.value;
  if((x>=0)&&(x<R.length))
   x=t.value.match(R[x]);
  for(i=0;i<x.length;i++)
   {
    var li=document.createElement('li');
    li.innerText=x[i];
    r.appendChild(li);
   }
 }
<textarea id="t" style="width:70%;height:12em">even, test; spider-man

But saying o'er what I have said before:
My child is yet a stranger in the world;
She hath not seen the change of fourteen years,
Let two more summers wither in their pride,
Ere we may think her ripe to be a bride.

—Shakespeare, William. The Tragedy of Romeo and Juliet</textarea>

<p><select id="s">
 <option selected>Select a regular expression</option>
 <!-- option value="1">/[a-z'\-]+/gi</option>
 <option value="2">/[a-z'\-\s]+/gi</option -->
</select></p>
 <ol id="r" style="display:block;width:auto;border:1px inner;overflow:scroll;height:8em;max-height:10em;"></ol>
</div>


1

@ stephen-sweriduk 솔루션 (더 흥미로 웠습니다!)부터 시작하여 좀 더 일반적이고 재사용 할 수 있도록 약간 수정했습니다.

/**
 * Adapted from: http://stackoverflow.com/questions/650022/how-do-i-split-a-string-with-multiple-separators-in-javascript
*/
var StringUtils = {

  /**
   * Flatten a list of strings
   * http://rosettacode.org/wiki/Flatten_a_list
   */
  flatten : function(arr) {
    var self=this;
    return arr.reduce(function(acc, val) {
        return acc.concat(val.constructor === Array ? self.flatten(val) : val);
    },[]);
  },

  /**
   * Recursively Traverse a list and apply a function to each item
   * @param list array
   * @param expression Expression to use in func
   * @param func function of (item,expression) to apply expression to item
   *
   */
  traverseListFunc : function(list, expression, index, func) {
    var self=this;
    if(list[index]) {
        if((list.constructor !== String) && (list[index].constructor === String))
            (list[index] != func(list[index], expression)) ? list[index] = func(list[index], expression) : null;
        (list[index].constructor === Array) ? self.traverseListFunc(list[index], expression, 0, func) : null;
        (list.constructor === Array) ? self.traverseListFunc(list, expression, index+1, func) : null;
    }
  },

  /**
   * Recursively map function to string
   * @param string
   * @param expression Expression to apply to func
   * @param function of (item, expressions[i])
   */
  mapFuncToString : function(string, expressions, func) {
    var self=this;
    var list = [string];
    for(var i=0, len=expressions.length; i<len; i++) {
        self.traverseListFunc(list, expressions[i], 0, func);
    }
    return self.flatten(list);
  },

  /**
   * Split a string
   * @param splitters Array of characters to apply the split
   */
  splitString : function(string, splitters) {
    return this.mapFuncToString(string, splitters, function(item, expression) {
      return item.split(expression);
    })
  },

}

그리고

var stringToSplit = "people and_other/things";
var splitList = [" ", "_", "/"];
var splittedString=StringUtils.splitString(stringToSplit, splitList);
console.log(splitList, stringToSplit, splittedString);

원래대로 되돌립니다.

[ ' ', '_', '/' ] 'people and_other/things' [ 'people', 'and', 'other', 'things' ]

1

이를 수행하는 쉬운 방법은 각 구분 기호를 사용하여 문자열의 각 문자를 처리하고 분할 배열을 작성하는 것입니다.

splix = function ()
{
  u = [].slice.call(arguments); v = u.slice(1); u = u[0]; w = [u]; x = 0;

  for (i = 0; i < u.length; ++i)
  {
    for (j = 0; j < v.length; ++j)
    {
      if (u.slice(i, i + v[j].length) == v[j])
      {
        y = w[x].split(v[j]); w[x] = y[0]; w[++x] = y[1];
      };
    };
  };

  return w;
};

용법: splix(string, delimiters...)

예: splix("1.23--4", ".", "--")

보고: ["1", "23", "4"]


1

그런 기능에 대한 고전적인 구현을 제공 할 것입니다. 이 코드는 거의 모든 버전의 JavaScript에서 작동하며 최적입니다.

  • 유지 관리하기 어려운 정규 표현식을 사용하지 않습니다.
  • JavaScript의 새로운 기능을 사용하지 않습니다
  • 더 많은 컴퓨터 메모리가 필요한 여러 .split () .join () 호출을 사용하지 않습니다.

순수한 코드 :

var text = "Create a function, that will return an array (of string), with the words inside the text";

println(getWords(text));

function getWords(text)
{
    let startWord = -1;
    let ar = [];

    for(let i = 0; i <= text.length; i++)
    {
        let c = i < text.length ? text[i] : " ";

        if (!isSeparator(c) && startWord < 0)
        {
            startWord = i;
        }

        if (isSeparator(c) && startWord >= 0)
        {
            let word = text.substring(startWord, i);
            ar.push(word);

            startWord = -1;
        }
    }

    return ar;
}

function isSeparator(c)
{
    var separators = [" ", "\t", "\n", "\r", ",", ";", ".", "!", "?", "(", ")"];
    return separators.includes(c);
}

https://codeguppy.com/code.html?IJI0E4OGnkyTZnoszAzf : 놀이터에서 실행중인 코드를 볼 수 있습니다


0

RegEx의 성능을 모르지만 RegEx의 또 다른 대안은 네이티브 HashSet을 활용하고 대신 O (max (str.length, delimeter.length)) 복잡성에서 작동합니다.

var multiSplit = function(str,delimiter){
    if (!(delimiter instanceof Array))
        return str.split(delimiter);
    if (!delimiter || delimiter.length == 0)
        return [str];
    var hashSet = new Set(delimiter);
    if (hashSet.has(""))
        return str.split("");
    var lastIndex = 0;
    var result = [];
    for(var i = 0;i<str.length;i++){
        if (hashSet.has(str[i])){
            result.push(str.substring(lastIndex,i));
            lastIndex = i+1;
        }
    }
    result.push(str.substring(lastIndex));
    return result;
}

multiSplit('1,2,3.4.5.6 7 8 9',[',','.',' ']);
// Output: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

multiSplit('1,2,3.4.5.6 7 8 9',' ');
// Output: ["1,2,3.4.5.6", "7", "8", "9"]

11
예, 실제로 작성한 것을 테스트 해보는 것은 어떻습니까? jsperf.com/slice-vs-custom 이것은이 예제에서 코드가 실제로 10 배 느리다는 것을 보여줍니다. 2 배 슬라이스, 2 배 concat, 1 배 분할, 1 배 시프트 및 길이 캐싱 없음이 성능에 도움이된다고 생각한 것은 무엇입니까?
Petar

코드를 업데이트했습니다. 이제 시프트, 분할 등이없는 최소 슬라이스 만 있습니다.
Orhun Alp Oral

0

가장 좋은 방법은 아니지만 여러 구분 기호 / 구분 기호로 분할하는 것이 좋습니다.

html

<button onclick="myFunction()">Split with Multiple and Different seperators/delimiters</button>
<p id="demo"></p>

자바 스크립트

<script>
function myFunction() {

var str = "How : are | you doing : today?";
var res = str.split(' | ');

var str2 = '';
var i;
for (i = 0; i < res.length; i++) { 
    str2 += res[i];

    if (i != res.length-1) {
      str2 += ",";
    }
}
var res2 = str2.split(' : ');

//you can add countless options (with or without space)

document.getElementById("demo").innerHTML = res2;
</script>

-3

정규 표현식을 사용합니다.

str =  'Write a program that extracts from a given text all palindromes, e.g. "ABBA", "lamal", "exe".';

var strNew = str.match(/\w+/g);

// Output: ["Write", "a", "program", "that", "extracts", "from", "a", "given", "text", "all", "palindromes", "e", "g", "ABBA", "lamal", "exe"]

1
이것은 회 문과 는 아무런 관계가 없으며 단지 단어입니다.
Nathan Tuggy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.