虽然我不建议为此使用正则表达式,但以下使用 String.prototype.split()、Array.prototype.shift() 和 Array.prototype.forEach() 似乎更容易:
function firstAndLast(el) {
// getting the text of the element:
var haystack = el.textContent,
// splitting that text on white-space sequences,
// forming an array:
names = haystack.split(/\s+/),
// getting the first element of that array:
first = names.shift(),
// initialising the 'last' variable to an empty string:
last = '';
// if the names array has a length greater than 1
// (there is more than one name):
if (names.length > 1) {
// last is assigned the last element of the array of names:
last = names.pop();
}
// return an array containing the first and last names:
return [first, last];
}
// getting all the <li> elements in the document:
var listItems = document.querySelectorAll('li'),
// creating an empty <span> element:
span = document.createElement('span'),
// an unitialised variable for use within the loop:
clone;
// iterating over each of the <li> elements, using
// Array.prototype.forEach(), and Function.prototype.call():
Array.prototype.forEach.call(listItems, function(li) {
// cloning the created <span>:
clone = span.cloneNode();
// setting the clone's text to the joined-together
// strings from the Array returned by the function:
clone.textContent = firstAndLast(li).join(' ');
// appending that cloned created-<span> to the
// current <li> element over which we're iterating:
li.appendChild(clone);
});
function firstAndLast(el) {
var haystack = el.textContent,
names = haystack.split(/\s+/),
first = names.shift(),
last = '';
if (names.length > 1) {
last = names.pop();
}
return [first, last];
}
var listItems = document.querySelectorAll('li'),
span = document.createElement('span'),
clone;
Array.prototype.forEach.call(listItems, function(li) {
clone = span.cloneNode();
clone.textContent = firstAndLast(li).join(' ');
li.appendChild(clone);
});
li span::before {
content: ' found: ';
color: #999;
}
li span {
color: #f90;
width: 5em;
}
<ol>
<li>Abc Def Ghi Jkl</li>
<li>Aéc Def Gài Mkl</li>
<li>Aéc-Def Gài Mkl</li>
<li>Aéc Def Gài-Mkl</li>
<li>Afd</li>
</ol>
JS Fiddle demo.
可以使用正则表达式,只是不必要地更复杂:
function firstAndLast(el) {
var haystack = el.textContent,
// matching a case-insensitive sequence of characters at the
// start of the string (^), that are in the range a-z,
// unicode accented characters, an apostrophe or
// a hyphen (escaped with a back-slash because the '-'
// character has a special meaning within regular
// expressions, indicating a range, as above) followed
// by a word-boundary (\b):
first = haystack.match(/^[a-z\u00C0-\u017F'\-]+\b/i),
// as above but the word-boundary precedes the string of
// of characters, and it matches a sequence at the end
// of the string ($):
last = haystack.match(/\b[a-z\u00C0-\u017F'\-]+$/i);
// if first exists (no matching regular expression would
// would return null) and it has a length:
if (first && first.length) {
// we assign the first element of the array returned by
// String.prototype.match() to the 'first' variable:
first = first[0];
}
if (last && last.length) {
// as above:
last = last[0];
}
// if the first and last variables are exactly equal,
// we return only the first; otherwise we return both
// first and last, in both cases within an array:
return first === last ? [first] : [first, last];
}
function firstAndLast(el) {
var haystack = el.textContent,
first = haystack.match(/^[a-z\u00C0-\u017F'\-]+\b/i),
last = haystack.match(/\b[a-z\u00C0-\u017F'\-]+$/i);
if (first && first.length) {
first = first[0];
}
if (last && last.length) {
last = last[0];
}
return first === last ? [first] : [first, last];
}
var listItems = document.querySelectorAll('li'),
span = document.createElement('span'),
clone;
Array.prototype.forEach.call(listItems, function(li) {
clone = span.cloneNode();
clone.textContent = firstAndLast(li).join(' ');
li.appendChild(clone);
});
li span::before {
content: ' found: ';
color: #999;
}
li span {
color: #f90;
width: 5em;
}
<ol>
<li>Abc Def Ghi Jkl</li>
<li>Aéc Def Gài Mkl</li>
<li>Aéc-Def Gài Mkl</li>
<li>Aéc Def Gài-Mkl</li>
<li>Afd</li>
</ol>
JS Fiddle demo.
参考资料: