Токенизиране на низове с помощта на регулярен израз в Javascript

Да предположим, че имам дълъг низ, съдържащ нови редове и раздели като:

var x = "This is a long string.\n\t This is another one on next line.";

И така, как можем да разделим този низ на токени, използвайки регулярен израз?

Не искам да използвам .split(' '), защото искам да науча Regex на Javascript.

По-сложен низ може да бъде следният:

var y = "This @is a #long $string. Alright, lets split this.";

Сега искам да извлека само валидните думи от този низ, без специални знаци и препинателни знаци, т.е. искам тези:

var xwords = ["This", "is", "a", "long", "string", "This", "is", "another", "one", "on", "next", "line"];

var ywords = ["This", "is", "a", "long", "string", "Alright", "lets", "split", "this"];

person Nawaz    schedule 09.12.2011    source източник
comment
На какво искаш да го разделиш? Казахте s.split(' '), но също така споменахте нови редове и раздели. Изглежда, че търсите урок за регулярен израз, който всъщност не е фокусът на Stack Overflow .   -  person nnnnnn    schedule 09.12.2011
comment
@nnnnnn: Чета този документ от MDN. Но в същото време правя някакъв експеримент. И това е първият ми опит да разделя изречението на думи.   -  person Nawaz    schedule 09.12.2011


Отговори (5)


Ето jsfiddle пример за това, което попитахте: http://jsfiddle.net/ayezutov/BjXw5/1/

По принцип кодът е много прост:

var y = "This @is a #long $string. Alright, lets split this.";
var regex = /[^\s]+/g; // This is "multiple not space characters, which should be searched not once in string"

var match = y.match(regex);
for (var i = 0; i<match.length; i++)
{
    document.write(match[i]);
    document.write('<br>');
}

АКТУАЛИЗАЦИЯ: По принцип можете да разширите списъка с разделителни знаци: http://jsfiddle.net/ayezutov/BjXw5/2/

var regex = /[^\s\.,!?]+/g;

АКТУАЛИЗАЦИЯ 2: През цялото време само букви: http://jsfiddle.net/ayezutov/BjXw5/3/

var regex = /\w+/g;
person Alexander Yezutov    schedule 09.12.2011
comment
И двата ви примера дават грешен резултат. Резултатът съдържа специални знаци. - person Nawaz; 09.12.2011
comment
Хей, мислех, че това е твоето намерение :) ако желаеш само букви в изхода: jsfiddle.net/ayezutov /BjXw5/3. var regex = /\w+/g; - person Alexander Yezutov; 09.12.2011
comment
+1. Това е добре. Изглежда, че това може да се напише по много различни начини. - person Nawaz; 09.12.2011
comment
Да, прав си. По принцип за английски \w е по-елегантна форма на [a-zA-Z0-9], но \w ще работи и с други езици. - person Alexander Yezutov; 09.12.2011
comment
изглежда като \S = ^\s - person Trinh Hoang Nhu; 05.10.2018

Използвайте \s+, за да токенизирате низа.

person Prince John Wesley    schedule 09.12.2011
comment
Това изглежда не работи. Направих var re = /\s+/; var words = re.exec(x); Какво правя грешно? - person Nawaz; 09.12.2011
comment
@Наваз var words = x.split(/\s+/); - person Kai; 09.12.2011
comment
@Nawaz Също така опитайте var words = y.split(/[^A-Za-z0-9]+/); да премахнете и препинателните знаци. - person Kai; 09.12.2011
comment
@Kai: От това помогна за първия низ. Но не работи с втория низ y. - person Nawaz; 09.12.2011

exec може да премине през съвпаденията, за да премахне знаци, които не са думи (\W).

var A= [], str= "This @is a #long $string. Alright, let's split this.",
rx=/\W*([a-zA-Z][a-zA-Z']*)(\W+|$)/g, words;

while((words= rx.exec(str))!= null){
    A.push(words[1]);
}
A.join(', ')

/*  returned value: (String)
This, is, a, long, string, Alright, let's, split, this
*/
person kennebec    schedule 09.12.2011

Ето решение, използващо групи регулярни изрази за токенизиране на текста с помощта на различни типове токени.

Можете да тествате кода тук https://jsfiddle.net/u3mvca6q/5/

/*
Basic Regex explanation:
/                   Regex start
(\w+)               First group, words     \w means ASCII letter with \w     + means 1 or more letters
|                   or
(,|!)               Second group, punctuation
|                   or
(\s)                Third group, white spaces
/                   Regex end
g                   "global", enables looping over the string to capture one element at a time

Regex result:
result[0] : default group : any match
result[1] : group1 : words
result[2] : group2 : punctuation , !
result[3] : group3 : whitespace
*/
var basicRegex = /(\w+)|(,|!)|(\s)/g;

/*
Advanced Regex explanation:
[a-zA-Z\u0080-\u00FF] instead of \w     Supports some Unicode letters instead of ASCII letters only. Find Unicode ranges here https://apps.timwhitlock.info/js/regex

(\.\.\.|\.|,|!|\?)                      Identify ellipsis (...) and points as separate entities

You can improve it by adding ranges for special punctuation and so on
*/
var advancedRegex = /([a-zA-Z\u0080-\u00FF]+)|(\.\.\.|\.|,|!|\?)|(\s)/g;

var basicString = "Hello, this is a random message!";
var advancedString = "Et en français ? Avec des caractères spéciaux ... With one point at the end.";

console.log("------------------");
var result = null;
do {
    result = basicRegex.exec(basicString)
    console.log(result);
} while(result != null)

console.log("------------------");
var result = null;
do {
    result = advancedRegex.exec(advancedString)
    console.log(result);
} while(result != null)

/*
Output:
Array [ "Hello",        "Hello",        undefined,  undefined ]
Array [ ",",            undefined,      ",",        undefined ]
Array [ " ",            undefined,      undefined,  " "       ]
Array [ "this",         "this",         undefined,  undefined ]
Array [ " ",            undefined,      undefined,  " "       ]
Array [ "is",           "is",           undefined,  undefined ]
Array [ " ",            undefined,      undefined,  " "       ]
Array [ "a",            "a",            undefined,  undefined ]
Array [ " ",            undefined,      undefined,  " "       ]
Array [ "random",       "random",       undefined,  undefined ]
Array [ " ",            undefined,      undefined,  " "       ]
Array [ "message",      "message",      undefined,  undefined ]
Array [ "!",            undefined,      "!",        undefined ]
null
*/
person Mar Cnu    schedule 30.11.2017

За да извлечем символи само с думи, използваме символа \w. Дали това ще съвпадне с Unicode символи или не, зависи от внедряването и можете да използвате тази справка за да видите какъв е случаят с вашия език/библиотека.

Моля, вижте отговора на Александър Йезутов (актуализация 2) за това как да приложите това в израз.

person awdz9nld    schedule 24.06.2012