简体   繁体   中英

RegEx for client-side server in Ruby on Rails

I'm doing server-side and client-side validation for names in my rails application. Currently, I have to duplicate the regular expression because the constant that works on the server is throwing an error. How can I modify the code so I don't have this duplication?

app/models/resident.rb

  NAME_FORMAT = /^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$/

  validate :name_is_acceptable, if: -> { (last_name_changed? || first_name_changed?) && (persisted? || !imported?) }
  def name_is_acceptable
    [:first_name, :last_name].each do |attr|
      value = self.send(attr)
      next if value.blank? || value =~ NAME_FORMAT

      errors.add attr, I18n.t(:resident_name_invalid, scope: 'errors.messages')
    end
  end

app/view/resident/_update.html.erb

<%= text_field_tag 'resident[last_name]', nil, class: 'form-control', placeholder: 'Last Name', required: true, maxlength: 50, pattern: '^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$', oninvalid: "setCustomValidity('Contains unsupported characters.')", oninput: "setCustomValidity('')" %>

error on clientside

Pattern attribute value (?-mix:^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$) is not a valid regular expression: Uncaught SyntaxError: Invalid regular expression: /(?-mix:^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$)/: Invalid group

I'm not so sure about your codes. It might be missing flags. Your expression seems to be working fine:

/^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$/m

Ruby Test

re = /^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$/m
str = 'abcàâä'

# Print the match result
str.scan(re) do |match|
    puts match.to_s
end

RegEx

You can modify/change your expressions in regex101.com .

RegEx Circuit

You can also visualize your expressions in jex.im :

在此处输入图片说明

JavaScript Demo

 const regex = /^(?!.*\\.\\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \\',.-]+$/gm; const str = `abcàâä`; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } // The result can be accessed through the `m`-variable. m.forEach((match, groupIndex) => { console.log(`Found match, group ${groupIndex}: ${match}`); }); } 

I decided to modify the Resident model with a new constant and work from there.

resident.rb

JS_NAME_FORMAT = '^(?!.*\.\S)[a-zA-Z àâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒößÖẞąćęłńóśźżĄĆĘŁŃÓŚŹŻìíòúÌÍÒÚáñÁÑ \',.-]+$'
NAME_FORMAT = /#{JS_NAME_FORMAT}/

_update.html.erb

<%= text_field_tag 'resident[last_name]', nil, class: 'form-control', placeholder: 'Last Name', required: true, maxlength: 50, pattern: Resident::JS_NAME_FORMAT, oninvalid: "setCustomValidity('Contains unsupported characters.')", oninput: "setCustomValidity('')" %>

Doing this I still only define express in a single spot, which my primary goal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM