РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ для сопоставления количества цифр, равного алфавиту в строке

#regex

#регулярное выражение

Вопрос:

Просто проверяю, возможно ли использовать регулярное выражение для проверки буквенно-цифровой строки, чтобы убедиться, что в ней одинаковое количество цифр и алфавита.

Например,

 7868HGCD (4 digits, 4 alphabets)
87429AJIGH (5 digits, 5 alphabets)
8A2K9H7A (digits ,alphabets alternately)
1H2B3C7D9K8L
  

..и список можно продолжить.

Любой синтаксис подходит до тех пор, пока цифра и алфавиты в строке в сумме равны. Я попробовал ^([a-zA-Z0-9 -] )$ , который принимает буквенно-цифровой формат, но я не знаю, какое регулярное выражение можно использовать для проверки (всего цифр = всего алфавитов)

Использую предварительный просмотр ^(?=[^s]?[0-9])(?=[^s]?[a-zA-Z])[a-zA-Z0-9]*$ , но он находит все строки, которые содержат хотя бы одну букву и одну цифру.

Комментарии:

1. Я не думаю, что регулярные выражения являются инструментом для использования здесь. То, что вы пытаетесь сделать, нарушает правила обычного языка.

2. На самом деле вы не можете считать с помощью регулярных выражений — используйте для этого выбранный вами язык программирования.

3. @Jan Ты не можешь считать с помощью регулярных выражений, но ты уверен, что можешь рассчитывать на них, ЛОЛ. Регулярное выражение спасает положение!

Ответ №1:

Я не знаю способа сделать это, используя чистое регулярное выражение, но если вы используете регулярное выражение вместе с языком приложения, то эта проблема проста. Например, в Java мы можем попробовать:

 String input = "7868HGCD";
if (input.replaceAll("[A-Z]", "").length() ==
    input.replaceAll("[0-9]", "").length()) {
    System.out.println("match");
}
else {
    System.out.println("no match");
}
  

Идея здесь в том, чтобы использовать регулярное выражение для разделения букв или цифр, в качестве альтернативы, а затем сравнить оставшиеся длины каждого из них.

Ответ №2:

Просто чтобы вложить свои два цента: вы могли бы написать себе небольшой синтаксический анализатор, например, в Python :

 from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor
from parsimonious.exceptions import ParseError

grammar = Grammar(
    r"""
    term        = (digit / alpha) 
    digit       = ~"d"
    alpha       = ~"[a-zA-Z]"
    """)

class AlnumCounter(NodeVisitor):
    def __init__(self):
        self.reset()

    def reset(self):
        self.abc = 0
        self.digits = 0

    def visit_digit(self, node, children):
        self.digits  = 1

    def visit_alpha(self, node, children):
        self.abc  = 1

    def visit_term(self, node, children):
        return (self.digits, self.abc)

    def generic_visit(self, node, visited_children):
        return node or visited_children

# list of strings
strings = ['7868HGCD', '87429AJIGH', '8A2K9H7A', '1H2B3C7D9K8L', 'somegarbage', 'parsing error']

alnum = AlnumCounter()
for string in strings:
    try:
        tree = grammar.parse(string)
        out = alnum.visit(tree)

        if out[0] == out[1]:
            print("Correct format: {}".format(string))
        else:
            print("Not correct: {}".format(string))

    except ParseError:
        print("Encountered strange characters within '{}'".format(string))

    finally:
        # reset the counters
        alnum.reset()
  

Это привело бы к

 Correct format: 7868HGCD
Correct format: 87429AJIGH
Correct format: 8A2K9H7A
Correct format: 1H2B3C7D9K8L
Not correct: somegarbage
Encountered strange characters within 'parsing error'
  

Комментарии:

1. Безумный, но, вероятно, самый эффективный способ решить эту проблему 1 (регулярное выражение всегда сопряжено с накладными расходами)

Ответ №3:

Это простое решение с использованием метода JavaScript match .

 var str = '7868HGCD';

console.log(str.match(/[a-zA-Z]/g).length == str.match(/[0-9]/g).length);