Concrete Javascript Regex for Accented Characters

2019-01-02 14:37发布

I've looked on Stack Overflow (replacing characters.. eh, how JavaScript doesn't follow the Unicode standard concerning RegExp, etc.) and haven't really found a concrete answer to the question:

How can JavaScript match for accented characters (those with diacritical marks)?

I'm forcing a field in a UI to match the format: last_name, first_name (last [comma space] first), and I want to provide support for diacritics, but evidently in JavaScript it's a bit more difficult than other languages/platforms.

This was my original version, until I wanted to add diacritic support:

/^[a-zA-Z]+,\s[a-zA-Z]+$/

Currently I'm debating one of three methods to add support, all of which I have tested and work (at least to some extent, I don't really know what the "extent" is of the second approach). Here they are:

Explicitly listing all accented characters that I would want to accept as valid (lame and overly-complicated):


var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
  • This correctly matches a last/first name with any of the supported accented characters in accentedCharacters.

My other approach was to use the . character class, to have a simpler expression:

var regex = /^.+,\s.+$/;
  • This would match for just about anything, at least in the form of: something, something. That's alright I suppose...

The last approach, which I just found might be simpler...

/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
  • It matches a range of unicode characters - tested and working, though I didn't try anything crazy, just the normal stuff I see in our language department for faculty member names.

Here are my concerns:

  1. The first solution is far too limiting, and sloppy and convoluted at that. It would need to be changed if I forgot a character or two, and that's just not very practical.
  2. The second solution is better, concise, but it probably matches far more than it actually should. I couldn't find any real documentation on exactly what . matches, just the generalization of "any character except the newline character" (from a table on the MDN).
  3. The third solution seems the be the most precise, but are there any gotchas? I'm not very familiar with Unicode, at least in practice, but looking at a code table/continuation of that table, \u00C0-\u017F seems to be pretty solid, at least for my expected input.

    • Faculty won't be submitting forms with their names in their native language (e.g., Arabic, Chinese, Japanese, etc.) so I don't have to worry about out-of-Latin-character-set characters

So the real question(s): Which of these three approaches is most suited for the task? Or are there better solutions?

7条回答
大哥的爱人
2楼-- · 2019-01-02 15:06

The accented Latin range \u00C0-\u017F was not quite enough for my database of names, so I extended the regex to

[a-zA-Z\u00C0-\u024F]
[a-zA-Z\u00C0-\u024F\u1E00-\u1EFF] // includes even more Latin chars

I added these code blocks (\u00C0-\u024F includes three adjacent blocks at once):

If you need more code points, you can find more ranges on Wikipedia's List of Unicode characters. For example, you could also add Latin Extended-C, D, and E, but I left them out because only historians seem interested in them now, and the D and E sets don't even render correctly in my browser.

The original regex stopping at \u017F borked on the name "Șenol". According to FontSpace's Unicode Analyzer, that first character is \u0218, LATIN CAPITAL LETTER S WITH COMMA BELOW. (Yeah, it's usually spelled with a cedilla-S \u015E, "Şenol." But I'm not flying to Turkey to go tell him, "You're spelling your name wrong!")

查看更多
墨雨无痕
3楼-- · 2019-01-02 15:09

What about this?

^([a-zA-Z]|[à-ú]|[À-Ú])+$

It will match every word with accented characters or not.

查看更多
时光乱了年华
4楼-- · 2019-01-02 15:12

The XRegExp library has a plugin named Unicode that helps solve tasks like this.

<script src="xregexp.js"></script>
<script src="addons/unicode/unicode-base.js"></script>
<script>
  var unicodeWord = XRegExp("^\\p{L}+$");

  unicodeWord.test("Русский"); // true
  unicodeWord.test("日本語"); // true
  unicodeWord.test("العربية"); // true
</script>

It's mentioned in the comments to the question, but it's easy to miss. I've noticed it only after I submitted this answer.

查看更多
高级女魔头
5楼-- · 2019-01-02 15:18

How about this?

/^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/
查看更多
人间绝色
6楼-- · 2019-01-02 15:23

Which of these three approaches is most suited for the task?

Depends on the task :-) To match exactly all Latin characters and their accented versions, the Unicode ranges probably provide the best solution. They might be extended to all non-whitespace characters, which could be done using the \S character class.

I'm forcing a field in a UI to match the format: last_name, first_name (last [comma space] first)

The most basic problem I'm seeing here are not diacritics, but whitespaces. There are a few names that consist of multiple words, e.g. for titles. So you should go with the most generic, that is allowing everything but the comma that distinguishes first from last name:

/[^,]+,\s[^,]+/

But your second solution with the . character class is just as fine, you only might need to care about multiple commata then.

查看更多
若你有天会懂
7楼-- · 2019-01-02 15:27

from this wiki : https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin

for latin letters, I use

/^[A-zÀ-ÖØ-öø-ÿ]+$/ 

it avoids hyphens and specials chars

查看更多
登录 后发表回答