簡體   English   中英

正則表達式:匹配包含數字和字母的字符串,但不包含只是數字的字符串

[英]Regex: Match a string containing numbers and letters but not a string of just numbers

我希望能夠使用單個正則表達式(如果可能)要求字符串適合[A-Za-z0-9_]但不允許:

  • 字符串只包含數字或/和符號。
  • 以符號開頭或結尾的字符串
  • 彼此相鄰的多個符號

有效

  • test_0123
  • t0e1s2t3
  • 0123_test
  • te0_s1t23
  • t_t

無效

  • t__t
  • ____
  • 01230123
  • _0123
  • _test
  • _test123
  • test_
  • test123_

規則的原因

這樣做的目的是過濾我正在處理的網站的用戶名。 出於特定原因,我已達到規則。

  • 僅包含數字和/或符號的用戶名可能會導致路由和數據庫查找出現問題。 /users/#{id}的路由允許id為用戶的id或用戶的名稱。 所以名稱和ID不應該碰撞。

  • _test看起來很奇怪,我不相信它是有效的子域名,即_test.example.com

  • 我不喜歡t__t作為子域的外觀。 t__t.example.com

這完全符合您的要求:

/\A(?!_)(?:[a-z0-9]_?)*[a-z](?:_?[a-z0-9])*(?<!_)\z/i
  1. 至少一個字母字符(中間的[az] )。
  2. 不以下划線開頭或結尾(開頭和結尾的(?!_)(?<!_) )。
  3. 字母字符前后可以包含任意數量的數字,字母或下划線,但每個下划線必須至少用一個數字或字母(其余部分)分隔。

編輯:事實上,由於正則表達式的其余部分是如何工作的,你可能甚至不需要前瞻/外觀?:第一個?:括號將在字母數字之后才允許下划線,第二個?:括號贏了“ t允許下划線除非它在字母數字之前:

/\A(?:[a-z0-9]_?)*[a-z](?:_?[a-z0-9])*\z/i

應該工作正常。

我確信你可以將所有這些都放到一個正則表達式中,但這並不簡單,我不確定為什么堅持它是一個正則表達式。 為什么不在驗證期間使用多次傳遞? 如果在用戶創建新帳戶時完成驗證檢查,則沒有任何理由嘗試將其填充到一個正則表達式中。 (也就是說,你只會一次處理一個項目,而不是數百或數千或更多。對於正常大小的用戶名,幾次通過應該花很少的時間,我想。)

如果名稱不包含至少一個數字,則首先拒絕; 如果名稱不包含至少一個字母,則拒絕; 然后檢查開始和結束是否正確; 這些傳遞中的每一個都可以是易於閱讀和易於維護的正則表達式。

關於什么:

/^(?=[^_])([A-Za-z0-9]+_?)*[A-Za-z](_?[A-Za-z0-9]+)*$/

它不使用后向引用。

編輯:

成功完成所有測試用例。 是否與ruby兼容。

這不會阻止“__”,但它確實得到了其余的:

([A-Za-z]|[0-9][0-9_]*)([A-Za-z0-9]|_[A-Za-z0-9])*

這是獲得所有規則的更長形式:

([A-Za-z]|([0-9]+(_[0-9]+)*([A-Za-z|_[A-Za-z])))([A-Za-z0-9]|_[A-Za-z0-9])*

dang,那很難看。 我同意Telemachus,你可能不應該用一個正則表達式來做這件事,即使它在技術上是可行的。 正則表達式通常是維護的痛苦。

這個問題要求一個正則表達式,並暗示它應該是匹配的正則表達式,這很好,並且由其他人回答。 但是,為了興趣,我注意到這些規則更容易直接表示為匹配的正則表達式。 即:

x !~ /[^A-Za-z0-9_]|^_|_$|__|^\d+$/
  • 除了字母,數字和_之外沒有其他字符
  • 不能以_開頭
  • 不能以_結尾
  • 不能連續兩個_s
  • 不能全部數字

你不能在Rails validates_format_of中以這種方式使用它,但你可以將它放在類的驗證方法中,我認為你有更好的機會仍然能夠理解你的意思,一個月或從現在起一年。

(?=.*[a-zA-Z].*)^[A-Za-z0-9](_?[A-Za-z0-9]+)*$

這個有效。

向前看以確保字符串中至少有一個字母,然后開始消耗輸入。 每次有下划線時,下一個下划線前必須有一個數字或一個字母。

干得好:

^(([a-zA-Z]([^a-zA-Z0-9]?[a-zA-Z0-9])*)|([0-9]([^a-zA-Z0-9]?[a-zA-Z0-9])*[a-zA-Z]+([^a-zA-Z0-9]?[a-zA-Z0-9])*))$

如果要限制要接受的符號,只需使用包含所有允許符號的[]更改所有[^ a-zA-Z0-9]

/^(?![\d_]+$)[A-Za-z0-9]+(?:_[A-Za-z0-9]+)*$/

您的問題與問題基本相同,並且要求至少有一個字符必須是字母。 負向前瞻 - (?![\\d_]+$) - 負責處理那部分,並且比將其融入基本正則表達式更容易(包括讀取和寫入),正如其他人試圖做的那樣。

[A-Za-z][A-Za-z0-9_]*[A-Za-z]

這適用於你的前兩個規則(因為它需要一個字母在開頭和結尾為第二個規則,它自動需要字母)。

我不確定第三條規則是否可以使用正則表達式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM