Tách các câu theo ',' và xóa các khoảng trắng xung quanh


82

Tôi có mã này:

var r = /(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*){0,}$/
var s = "   a   ,  b  , c "
var m = s.match(r)
m => ["   a   ,  b  , c ", "a", "c"]

Có vẻ như toàn bộ chuỗi đã được khớp, nhưng đã "b"biến đi đâu? Tôi muốn nhận được:

["   a   ,  b  , c ", "a", "b", "c"]

để tôi có thể thực hiện m.shift()với một kết quả như s.split(',')nhưng cũng có thể loại bỏ khoảng trắng.

Tôi có sai sót trong regexp hay tôi hiểu nhầm String.prototype.match?


Như một lưu ý phụ, {0,}cũng giống như *.
pimvdb

tốt, scũng có thể ' a, c'hay'a,b,c d e, f'
meandre

tôi sẽ thay đổi không gian thành \ s
mondre

Câu trả lời:


190

Đây là một cách khá đơn giản và dễ hiểu để thực hiện việc này mà không cần biểu thức chính quy phức tạp.

var str = "   a   ,  b  , c "
var arr = str.split(",").map(function(item) {
  return item.trim();
});
//arr = ["a", "b", "c"]

Bản gốc .mapđược hỗ trợ trên IE9 trở lên: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map


Hoặc trong ES6 + nó thậm chí còn ngắn hơn:

var arr = str.split(",").map(item => item.trim());

Và để hoàn thành, nó ở đây trong Typecript với thông tin nhập

var arr: string[] = str.split(",").map((item: string) => item.trim());

4
Chỉ cần được kén cá chọn canh, bạn có thể loại bỏ các dấu ngoặc xung quanh tranh cãi bản đồ: var arr = str.split(",").map(item=>item.trim());
David Jones

Tôi với @DavidJones trên cái này. Nếu bạn sửa đổi câu trả lời của bạn sẽ là tuyệt vời. Đã giúp tôi rất nhiều cho trường hợp của tôi, cảm ơn các bạn!
Alreadytakenindeed

Đúng là điểm tốt - câu trả lời được cập nhật để phản ánh điều đó! Cá nhân tôi luôn thêm các dấu ngoặc đơn vì tôi thường viết các Typecript và tôi muốn cung cấp thông tin về loại rõ ràng để bạn luôn có thể biết thứ gì đó trong nháy mắt.
CBarr

Đây là một câu trả lời tuyệt vời Chris.
theo chu kỳ

Đơn giản và tốt nhất !!
Rahul Sonwanshi

22

Bạn có thể thử điều này mà không cần biểu thức chính quy phức tạp.

var arr = "   a   ,  b  , c ".trim().split(/\s*,\s*/);
console.log(arr);


15

Câu trả lời ngắn gọn: Sử dụng m = s.match(/[^ ,]/g);


RE của bạn không hoạt động như mong đợi, bởi vì nhóm cuối cùng khớp với trận đấu gần đây nhất (= c). Nếu bạn bỏ qua {1,}$, kết quả trùng khớp sẽ được trả về " a , b ", "a", "b". Tóm lại, RegExp của bạn trả về nhiều kết quả phù hợp như các nhóm được chỉ định trừ khi bạn sử dụng globalcờ /g. Trong trường hợp này, danh sách trả về giữ các tham chiếu đến tất cả các chuỗi con phù hợp.

Để đạt được hiệu quả của bạn, hãy sử dụng:

m = s.replace(/\s*(,|^|$)\s*/g, "$1");

Sự thay thế này thay thế mọi dấu phẩy ( ,), đầu ( ^) và cuối ( $), được bao quanh bởi khoảng trắng, bằng ký tự gốc ( commahoặc không có gì).

Nếu bạn muốn lấy một mảng, hãy sử dụng:

m = s.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/);

RE này cắt xén chuỗi (loại bỏ tất cả khoảng trắng ở đầu và cuối, sau đó chia chuỗi theo <any whitespace>,<any whitespace>. Lưu ý rằng các ký tự khoảng trắng cũng bao gồm các dòng và tab mới. Nếu bạn muốn chỉ sử dụng khoảng trắng, hãy sử dụng dấu cách ( ) thay vì \s.


@Andrew Tôi đã mở rộng giải thích về RE của bạn. Xem ví dụ thứ hai của tôi để biết một splitphương pháp.
Rob W

tôi đã đăng nó dưới dạng bình luận cho một câu trả lời khác. Tôi tự hỏi, tôi có thể làm điều đó với một regexp và một hoạt động hay js regexp không đủ thông minh?
urndre

@Andrew Có, chỉ cần sử dụng s.match(/[^ ,]+/g). Như đã đề cập ở đầu câu trả lời của tôi, /gcờ toàn cục, trả về tất cả các chuỗi con phù hợp.
Rob W

@Andrew: Một nhóm chụp sẽ tạo ra một đối sánh, bất kể bạn thêm bao nhiêu bộ định lượng. Nếu bạn muốn kết hợp a, bc, bạn cần ba cặp ngoặc đơn (không bao gồm (?:...)):/(?:^\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)(?:,\s*([^\s]*)\s*)$/
user123444555621

@RobW, s.match (/ [^,] + / g) hoạt động chính xác như tôi cần, hãy thêm nó vào câu trả lời của bạn
meandre


8

Bạn có thể làm điều này cho mục đích của mình
CHỈNH SỬA : Loại bỏ thay thế thứ hai như được đề xuất trong các nhận xét. s.replace(/^\s*|\s*$/g,'').split(/\s*,\s*/)
Đầu tiên replacecắt chuỗi và sau đó splithàm chia nhỏ xung quanh '\s*,\s*'. Điều này cho kết quả ["a", "b", "c"]đầu vào " a , b , c "

Đối với lý do tại sao regex của bạn không chụp 'b', bạn đang lặp lại một nhóm đã được chụp, vì vậy chỉ lần xuất hiện cuối cùng mới được chụp. Thông tin thêm về điều đó tại đây http://www.regular-expressions.info/captureall.html


tôi không muốn xóa tất cả các khoảng trắng, chỉ xung quanh dấu phẩy hoặc ở đầu / cuối của một chuỗi
urndre

@Andrew không phải là tất cả các khoảng trắng sao? hoặc bạn có câu nào bạn muốn tách?
David Hellsing

s.replace (/ ^ \ s * /, '') .replace (/ \ s * $ /, '') .split (/ \ s *, \ s * /) có thể làm được điều này
urndre

@Andrew Đã thay đổi câu trả lời theo yêu cầu của bạn.
Narendra Yadala

6

vì vậy cuối cùng tôi đã đi với /(?=\S)[^,]+?(?=\s*(,|$))/g, cung cấp chính xác những gì tôi cần: tất cả các câu được chia theo ',' mà không có dấu cách xung quanh.

'       a,    OMG     abc b a b, d o WTF        foo     '.
  match( /(?=\S)[^,]+?(?=\s*(,|$))/g )
=> ["a", "OMG     abc b a b", "d o WTF        foo"]

cảm ơn nhiều!


đây là ý nghĩa như tôi hiểu nó. vui lòng sửa cho tôi nếu tôi không đúng: (?=\S)- chỉ bắt đầu chụp khi không có khoảng trắng ở phía trước [^,]+- chụp càng nhiều 'không phải dấu phẩy' càng tốt ?- nhưng không chụp những gì nhóm tiếp theo có thể chụp (?=\s*(,|$))- chụp tất cả các khoảng trắng trước đó một dấu phẩy hoặc cuối chuỗi /g- lặp lại qua tất cả các chuỗi
meandre

1

Nếu bạn muốn tiếp tục sử dụng biểu thức chính quy, hãy giữ mã đơn giản và không sử dụng ES6:

s.replace(/ /g, '').split(",")

1 - Thay thế tất cả các khoảng trắng (/ / g) bằng các chuỗi trống ('')

2 - Sau đó chia nó thành một mảng

Et thì đấy


Đây là câu trả lời tốt nhất, ít phức tạp nhất.
Blazes
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.